JSPatch
JSPatch copied to clipboard
NSMutableArray在返回时会被转换成NSArray
你好,NSMutableArray在返回时会被转换成NSArray,我们的项目在其它地方用的NSMutableArray结束的参数,导致这样的传参会崩溃,请问怎么解决?
NSMutableArray不会被转换成NSArray。
这是我们的OC代码
下面是我们写的JS代码:
下面是报错信息:
报错在了这个地方
finished(customProcessArray, firmProcessArray, response, error);
请问是什么原因呢?谢谢
@bang590 请问是什么原因呢?该如何该呢?
你不是自己把它变成NSArray了吗
我这么写他也会报错:
var customProcessArray = NSMutableArray.alloc().init(); var firmProcessArray = NSMutableArray.alloc().init();
@bang590 ,这是为什么啊?
看不出问题,你这么写在OC断点看到传过去是什么对象?
@bang590 接着@PWDream的提问:
1、
这是NSMutableArray不是NSArray
2、还没回传到OC就报错了所以在OC中断不到
是在js中的这步报的错
可以简化成一个demo工程发来看看吗
@bang590 写了个小demo没有报错但是使用可变数组(NSMutableArray)作为block的参数没有回调成功,使用不可变数组(NSArray)作为block的参数就可以回调成功 下面是代码
OC代码
- (void)setupView {
self.view.backgroundColor = [UIColor redColor];
UIButton *button1 = [UIButton buttonWithType:UIButtonTypeCustom];
button1.frame = CGRectMake(100, 200, 100, 50);
[button1 setTitle:@"button1" forState:UIControlStateNormal];
[button1 setBackgroundColor:[UIColor greenColor]];
[button1 addTarget:self action:@selector(buttonAction1) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button1];
UIButton *button2 = [UIButton buttonWithType:UIButtonTypeCustom];
button2.frame = CGRectMake(100, 300, 100, 50);
[button2 setTitle:@"button2" forState:UIControlStateNormal];
[button2 setBackgroundColor:[UIColor purpleColor]];
[button2 addTarget:self action:@selector(buttonAction2) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button2];
}
- (void)buttonAction1 {
[self getData1:^(NSArray *result1, NSArray *result2) {
NSLog(@"%s",__FUNCTION__);
NSLog(@"%@\n=========================\n%@",result1,result2);
}];
}
- (void)getData1:(void(^)(NSArray *result1,NSArray *result2))finished {
NSMutableArray *result = [NSMutableArray array];
for (int i = 0; i < 5; i ++) {
[result addObject:@"aa"];
}
finished ? finished(result,result) : nil;
}
- (void)buttonAction2 {
[self getData2:^(NSMutableArray *result1, NSMutableArray *result2) {
NSLog(@"%s",__FUNCTION__);
NSLog(@"%@\n=========================\n%@",result1,result2);
}];
}
- (void)getData2:(void(^)(NSMutableArray *result1,NSMutableArray *result2))finished {
NSMutableArray *result = [NSMutableArray array];
for (int i = 0; i < 5; i ++) {
[result addObject:@"bb"];
}
finished ? finished(result,result) : nil;
}
JS代码
require('NSMutableArray');
defineClass('JSPathTestViewController',{
getData1: function(finished) {
var result = NSMutableArray.array();
for (var i = 0; i < 5; i++) {
result.addObject('aa');
}
if (finished) {
finished(result, result)
}
},
getData2: function(finished) {
var result = NSMutableArray.array();
for (var i = 0; i < 5; i++) {
result.addObject('bb');
}
if (finished) {
finished(result, result)
}
}
})
明白了
- OC 通过 JavaScriptCore 跟 JS 通信,若 OC 返回 NSMutableArray 到 JS,会被自动转成 JS 的 Array 类型。
- JS 的 Array 类型传到 OC 会自动转为 NSArray 类型。
- 方法调用里 NSMutableArray 没有这个转换问题是因为 JSPatch 用 JPBoxing 装箱的方式封装了。
- 一个 block 通过 JavaScriptCore 从 OC 传到 JS 会自动转为 JS Function 类型,可以直接调用这个 Function。
- JSPatch 在调用这个 Function (finished) 之前会把参数通过 OC 里的 formatJSToOC 方法转换,主要是处理 JPBoxing 拆箱,NSMutableArray 在这里被转为 JS Array 类型,再传入这个block进入OC就会变成 NSArray。
- 若要解决这个问题,就不能让 block 传到 JS 时自动转为 function,要通过类似 JPBoxing 装箱的方式传到 JS,调用时再回到 OC 调用。但在 OC 调用时不知道这个 block 的参数类型和参数个数,无法进行调用,暂时没想到方法解决。
明白了,thx