Skip to content

defineClass使用文档

bang edited this page Jul 27, 2015 · 5 revisions

##API

defineClass(classDeclaration, instanceMethods, classMethods)

@param classDeclaration: 字符串,类名/父类名和Protocol
@param instanceMethods: 要添加或覆盖的实例方法
@param classMethods: 要添加或覆盖的类方法

覆盖方法

  1. 在 defineClass 里定义 OC 已存在的方法即可覆盖,方法名规则与调用规则一样,使用 _ 分隔:
// OC
@implementation JPTestObject
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
@end
// JS
defineClass("JPTableViewController", {
  tableView_didSelectRowAtIndexPath: function(tableView, indexPath) {
    ...
  },
})
  1. 使用双下划线 __ 代表原OC方法名里的下划线 _ :
// OC
@implementation JPTableViewController
- (NSArray *) _dataSource {
}
@end
// JS
defineClass("JPTableViewController", {
  __dataSource: function() {
  },
})
  1. 在方法名前加 ORIG 即可调用未覆盖前的 OC 原方法:
// OC
@implementation JPTableViewController
- (void) viewDidLoad {
}
@end
// JS
defineClass("JPTableViewController", {
  viewDidLoad: function() {
     self.ORIGviewDidLoad();
  },
})

Super / Property / Member variables

  1. 使用 self.super() 接口代表 super 关键字,调用 super 方法:
// JS
defineClass("JPTableViewController", {
  viewDidLoad: function() {
     self.super().viewDidLoad();
  }
})
  1. 用调用方法的方式获取/修改在 OC 定义的 Property:
// OC
@interface JPTableViewController
@property (nonatomic) NSArray *data;
@end
@implementation JPTableViewController
@end
// JS
defineClass("JPTableViewController", {
  viewDidLoad: function() {
     var data = self.data()     //get property value
     self.setData(data.toJS().push("JSPatch")     //set property value
  },
})
  1. 使用 getProp()setProp_forKey() 获取/添加/修改新的 Property:
// OC
@interface JPTableViewController
@end
@implementation JPTableViewController
@end
// JS
defineClass("JPTableViewController", {
  init: function() {
     self = self.super().init()
     self.setProp_forKey("JSPatch", "data")     //添加新的 Property (id data)
     return self;
  }
  viewDidLoad: function() {
     var data = self.getProp("data")     //获取新的 Property 值
  },
})
  1. 使用 valueForKey()setValue_forKey() 获取/修改私有成员变量:
// OC
@implementation JPTableViewController {
     NSArray *_data;
}
@end
// JS
defineClass("JPTableViewController", {
  viewDidLoad: function() {
     var data = self.valueForKey("_data")     //get member variables
     self.setValue_forKey(["JSPatch"], "_data")     //set member variables
  },
})

添加新方法

可以给一个类随意添加 OC 未定义的方法,但所有的参数类型都是 id:

// OC
@implementation JPTableViewController
- (void)viewDidLoad
{
     NSString* data = [self dataAtIndex:@(1)];
     NSLog(@"%@", data);      //output: Patch
}
@end
// JS
var data = ["JS", "Patch"]
defineClass("JPTableViewController", {
  dataAtIndex: function(idx) {
     return idx < data.length ? data[idx]: ""
  }
})

Protocol

可以在定义时让一个类实现某些 Protocol 接口,写法跟 OC 一样:

defineClass("JPViewController: UIViewController<UIScrollViewDelegate, UITextViewDelegate>", {

})

这样做的作用是,当添加 Protocol 里定义的方法,而类里没有实现的方法时,参数类型不再全是 id,而是自动转为 Protocol 里定义的类型:

@protocol UIAlertViewDelegate <NSObject>
...
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex;
...
@end
defineClass("JPViewController: UIViewController <UIAlertViewDelegate>", {
  viewDidAppear: function(animated) {
    var alertView = require('UIAlertView')
      .alloc()
      .initWithTitle_message_delegate_cancelButtonTitle_otherButtonTitles(
        "Alert",
        self.dataSource().objectAtIndex(indexPath.row()), 
        self, 
        "OK", 
        null
      )
     alertView.show()
  }
  alertView_clickedButtonAtIndex: function(alertView, buttonIndex) {
    console.log('clicked index ' + buttonIndex)
  }
})
Clone this wiki locally