JSPatch icon indicating copy to clipboard operation
JSPatch copied to clipboard

OC block becomes JS object, not function

Open view-ing opened this issue 9 years ago • 8 comments

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 pointer of basic type, there is no official documentation to explain.
  • Suggestion: We can box the above pointer in OC, unbox in JS.

view-ing avatar Aug 07 '16 06:08 view-ing

JSPatch is support both block and pointer types. How is the executeBlockPointer define in OC?

bang590 avatar Aug 07 '16 14:08 bang590

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

view-ing avatar Aug 07 '16 15:08 view-ing

知道你的意思了,还是说中文吧:( executeBlockPointer是在JS新增的方法,默认JS里新增的方法参数类型都是id,所以这里参数block是被识别成id类型的,不是函数。 如果executeBlockPointer在OC有定义并指明它的参数类型是block,这样写是没问题的。 若新增方法参数需要是别的类型,可以用defineProtocol,详见文档,不过也不支持block类型。 这种在OC调用JS新增的方法似乎除了debug外不会有场景遇到。

bang590 avatar Aug 07 '16 15:08 bang590

不是这样的,就算在OC中有executeBlockPointer方法,但是因该block参数中的参数含有BOOL *, 当调用到JS后,block还是不能被识别成function而是object;如果block中的参数不含有基本类型的指针,JS是能识别的,我主要是现在正好出现在该场景才发现的。直接用JavascriptCore也会这样。

view-ing avatar Aug 07 '16 15:08 view-ing

喔对,不好意思没仔细看第二条回复,确实不支持参数类型是指针的block。要通过box/unbox支持的话……相当麻烦,再看看能不能通过扩展的方式支持

bang590 avatar Aug 07 '16 16:08 bang590

如果JSPatch的思想是类似于RN,OC与JS之间的通讯都是基于string建立的索引,感觉这样很多问题都会迎仍而解

view-ing avatar Aug 07 '16 16:08 view-ing

另外有个问题,能否强制JS的垃圾回收?

view-ing avatar Aug 07 '16 16:08 view-ing

  1. 基于string建索引能解决的问题似乎只有这个特殊block问题和延迟释放,但可能会带来其他问题,待研究。
  2. 有个私有API JSSynchronousGarbageCollectForDebugging 可以强制垃圾回收,AppStore不通过。

bang590 avatar Aug 08 '16 00:08 bang590