defineClass使用文档
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) { ... },})
2.使用双下划线 __ 代表原OC方法名里的下划线 _ :
// OC
@implementation JPTableViewController- (NSArray *) _dataSource {}@end
// JS
defineClass("JPTableViewController", { __dataSource: function() { },})
3.在方法名前加 ORIG 即可调用未覆盖前的 OC 原方法:
// OC
@implementation JPTableViewController
- (void) viewDidLoad {}@end
// JS
defineClass("JPTableViewController", { viewDidLoad: function() { self.ORIGviewDidLoad(); },})
覆盖类方法
defineClass() 第三个参数就是要添加或覆盖的类方法,规则与上述覆盖实例方法一致:
// OC
@implementation JPTestObject
+ (void)shareInstance{}@end
// JS
defineClass("JPTableViewController", { //实例方法}, { //类方法 shareInstance: function() { ... },})
Super
使用 self.super() 接口代表 super 关键字,调用 super 方法:
// JS
defineClass("JPTableViewController", { viewDidLoad: function() { self.super().viewDidLoad(); }})
Property
获取/修改 OC 定义的 Property用调用 getter / setter 的方式获取/修改已在 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 },})
动态新增 Property
若要在 JS 为类新增 Property,可以使用 getProp() 和 setProp_forKey() 这两个接口。注意 getProp() 无法获取在 OC 定义的 Property,只能获取在 JS 通过 setProp_forKey() 接口设置的 Property。
// OC
@interface JPTableViewController@end@implementation JPTableViewController@end// JSdefineClass("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 值 },})
私有成员变量
使用 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 里的接口,需要在 defineClass 的类声明参数里指明实现的 Protocol,详见下文。
Protocol
可以在定义时让一个类实现某些 Protocol 接口,写法跟 OC 一样:
defineClass("JPViewController: UIViewController", {})
这样做的作用是,当添加 Protocol 里定义的方法,而类里没有实现的方法时,参数类型不再全是 id,而是自动转为 Protocol 里定义的类型:
@protocol UIAlertViewDelegate...
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex;...@enddefineClass("JPViewController: UIViewController", {
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)
}
})
最后附上官方的转换工具:
https://github.com/bang590/JSPatchConvertor