Skip to content

基础用法

yangyangFeng edited this page Jul 2, 2019 · 28 revisions

0. 索引

1. require

在使用Objective-C类之前需要调用 _import('className’) :

_import('UIView')
var view = UIView.alloc().init()

可以用逗号 , 分隔,一次性导入多个类:

_import('UIView, UIColor')
var view = UIView.alloc().init()
var red = UIColor.redColor()

或者直接在使用时才调用 require() :

_import('UIView').alloc().init()

2. 调用OC方法

调用类方法

var redColor = UIColor.redColor();

调用实例方法

var view = UIView.alloc().init();
view.setNeedsLayout();

参数传递

跟在OC一样传递参数:

var view = UIView.alloc().init();
var superView = UIView.alloc().init()
superView.addSubview(view)

Property

获取/修改 Property 等于调用这个 Property 的 getter / setter 方法,获取时记得加 ():

view.setBackgroundColor_(redColor);
var bgColor = view.backgroundColor();

方法名转换

多参数方法名使用 _ 分隔:

var indexPath = require('NSIndexPath').indexPathForRow_inSection(0, 1);

若原 OC 方法名里包含下划线 _,在 JS 使用双下划线 __ 代替:

// Obj-C: [JPObject _privateMethod];
JPObject.__privateMethod()

3. defineClass

API

defineClass(classDeclaration, instanceMethods, classMethods)

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

覆盖方法

1.在 defineClass 里定义 OC 已存在的方法即可覆盖,方法名规则与调用规则一样,使用 _ 分隔:

// OC
@implementation JPTableViewController
- (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.在方法名前加 tt 即可调用未覆盖前的 OC 原方法:

// OC
@implementation JPTableViewController
- (void)viewDidLoad {
}
@end
// JS
defineClass("JPTableViewController", {
  viewDidLoad: function() {
     self.ttviewDidLoad();
  },
})

覆盖类方法

defineClass() 第三个参数就是要添加或覆盖的类方法,规则与上述覆盖实例方法一致:

// OC
@implementation JPTestObject
+ (void)shareInstance
{
}
@end
// JS
defineClass("JPTableViewController", {
  //实例方法
}, {
  //类方法
  shareInstance: function() {
    ...
  },
})

覆盖 Category 方法

覆盖 Category 方法与覆盖普通方法一样:

@implementation UIView (custom)
- (void)methodA {
}
+ (void)clsMethodB {
}
@end
defineClass('UIView', {
  methodA: function() {
  }
}, {
  clsMethodB: function() {
  }
});

Super

使用 Super() 接口代表 super 关键字,调用 super 方法:

// JS
defineClass("JPTableViewController", {
  viewDidLoad: function() {
     Super().viewDidLoad();
  }
})

Property

获取/修改 OC 定义的 Property

用调用 getter / setter 的方式获取/修改已在 OC 定义的 Property:

动态新增 Property

可以在 name:property() 为属性

defineClass("JPTableViewController", {
  //添加属性
  name:property()
  init: function() {
     self = Super().init()
     self.setData_(["a", "b"])     //添加新的 Property (id data)
     self.setTotalCount_(2)
     return self
  },
  viewDidLoad: function() {
     var data = self.data()     //获取 Property 值
     var totalCount = self.totalCount()
  },
})

私有成员变量

使用 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]: ""
  }
})

4. 特殊类型

Struct

JSPatch原生支持 CGRect / CGPoint / CGSize / NSRange 这四个 struct 类型,用 JS 对象表示:

// Obj-C
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(20, 20, 100, 100)];
[view setCenter:CGPointMake(10,10)];
[view sizeThatFits:CGSizeMake(100, 100)];


// JS
var view = UIView.alloc().initWithFrame(new TTReact(x:20, y:20, width:100, height:100))
view.setCenter(new TTPoint(x: 10, y: 10))
view.sizeThatFits(new TTSize(width: 100, height:100))

Selector

在JS使用字符串代表 Selector:

//Obj-C
[self performSelector:@selector(viewWillAppear:) withObject:@(YES)];
//JS
self.performSelector_withObject("viewWillAppear:", 1)

13. 调试

可以使用 console.log() 打印一个对象,作用相当于 NSLog(),会直接在 XCode 控制台打出。

console.log() 支持任意参数,但不支持像 NSLog 这样 NSLog(@"num:%f", 1.0) 的拼接:

var view = UIView.alloc().init();
var str = "test";
var num = 1;
console.log(view, str, num)
console.log(str + num);   //直接在JS拼接字符串

也可以通过 Safari 的调试工具对 JS 进行断点调试,详见 JS 断点调试

Clone this wiki locally