OC block becomes JS object, not function
The Demo as follows
[OC Codes]
typedef void (^JPBlockWithParamPointer)(BOOL *p1);
@implementation JPViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(0, 100, [UIScreen mainScreen].bounds.size.width, 50)];
[btn setTitle:@"Push JPTableViewController" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(handleBtn:) forControlEvents:UIControlEventTouchUpInside];
[btn setBackgroundColor:[UIColor grayColor]];
[self.view addSubview:btn];
}
- (void)handleBtn:(id)sender {
[self executeBlockPointer:^(BOOL *p1) {
}];
}
@end
[JS Codes]
defineClass('JPViewController', {
executeBlockPointer: function (blockHandler) {
console.log(typeof (blockHandler));
console.log(blockHandler instanceof Function);
console.log(blockHandler);
},
})
The Problems
When we execute function executeBlockPointer in js, the result of console.log(typeof (blockHandler)); is object not function.
The Guess and Suggestion
- Guess: JSCore doesn't support the
pointerof basic type, there is no official documentation to explain. - Suggestion: We can box the above
pointerin OC, unbox in JS.
JSPatch is support both block and pointer types.
How is the executeBlockPointer define in OC?
How to define executeBlockPointer is no point. Even though, I don't have this function, JSPatch can load it on hot.
Mainly,
[self executeBlockPointer:^(BOOL *p1) {
}];
the function executeBlockPinter has a parameter of block, and parameters of the block is BOOL *. when the function execute into JS, the block doesn't become function but object
知道你的意思了,还是说中文吧:(
executeBlockPointer是在JS新增的方法,默认JS里新增的方法参数类型都是id,所以这里参数block是被识别成id类型的,不是函数。
如果executeBlockPointer在OC有定义并指明它的参数类型是block,这样写是没问题的。
若新增方法参数需要是别的类型,可以用defineProtocol,详见文档,不过也不支持block类型。
这种在OC调用JS新增的方法似乎除了debug外不会有场景遇到。
不是这样的,就算在OC中有executeBlockPointer方法,但是因该block参数中的参数含有BOOL *, 当调用到JS后,block还是不能被识别成function而是object;如果block中的参数不含有基本类型的指针,JS是能识别的,我主要是现在正好出现在该场景才发现的。直接用JavascriptCore也会这样。
喔对,不好意思没仔细看第二条回复,确实不支持参数类型是指针的block。要通过box/unbox支持的话……相当麻烦,再看看能不能通过扩展的方式支持
如果JSPatch的思想是类似于RN,OC与JS之间的通讯都是基于string建立的索引,感觉这样很多问题都会迎仍而解
另外有个问题,能否强制JS的垃圾回收?
- 基于string建索引能解决的问题似乎只有这个特殊block问题和延迟释放,但可能会带来其他问题,待研究。
- 有个私有API
JSSynchronousGarbageCollectForDebugging可以强制垃圾回收,AppStore不通过。