我有一个简单的函数,它将完成处理程序作为JSValue。它是一个JSValue,因为我使用这个函数作为JSExport协议的一部分。
然后,此函数使用另一个完成处理程序调用另一个内部方法。当调用第二个处理程序时,我想在JSValue上调用WithArguments。
当我从第二个完成处理程序外部调用WithAnguments时,这一切都按预期工作,但是从第二个处理程序调用时我得到一个BAD_ACCESS。
func myFunction(completion: JSValue) {
// If I put completion.callWithAttributes([]) here, everything works fine.
self.mySecondFunction(completion: {(result: Dictionary<String, AnyObject>) -> Void in
// If I put completion.callWithAttributes([]) here, I get a BAD_ACCESS
})
}
任何帮助非常感谢。谢谢!
答案 0 :(得分:0)
我强烈建议您执行以下操作
[self.callback.context[@"setTimeout"]
callWithArguments:@[callback, @0, items]];
当您要向JavaScriptCore对应方发送响应时。这将阻止TVML UI MainThread挂起。正如您所看到的那样,调用setTimeout javascript函数时延迟为0,您的回调和项目作为参数如下:
setTimeout(callback,0,items)
我不知道你是怎么创建警报的,不管怎么说这是Apple的一个:
createAlert : function(title, description) {
var alertString = `<?xml version="1.0" encoding="UTF-8" ?>
<document>
<alertTemplate>
<title>${title}</title>
<description>${description}</description>
<button class="btn_close">
<text>OK</text>
</button>
</alertTemplate>
</document>`
var parser = new DOMParser();
var alertDoc = parser.parseFromString(alertString, "application/xml");
return alertDoc
}
与警报和您在此处看到的行为没有直接关系,这更像是调用此事件的副作用
completion.callWithArguments([])
以一种意想不到的方式。最好在某处保存完成,并在对象实例上获取它的引用。然后,当长任务结束时,你调用它。此外,如果你执行一项长期任务,那么你在NSOperation中移动所有内容是合理的:
/** JavaScriptCore Callback Operation */
@interface JSCallbackOperation: NSOperation
@property(nonatomic, strong) JSValue*callback;
@property(nonatomic, strong) id items;
@end
@implementation JSCallbackOperation
- (id)initWithItems:(id)items callback:(JSValue*)callback {
if(self = [super init]) {
self.items=items;
self.callback=callback;
}
return self;
}
- (void)main {
@autoreleasepool {
if(self.callback) {
NSLog(@"Dispatching %@", self.callback);
[self.callback.context[@"setTimeout"]
callWithArguments:@[self.callback, @0, self.items]];
}
}
}
此时你定义一个帮助器,用参数调用回调:
#pragma mark - API Helper
- (void)handleResponseWithItems:(id)items callback:(JSValue*)callback {
NSArray *active_and_pending_operations = operationQueue.operations;
NSInteger count_of_operations = operationQueue.operationCount;
NSLog(@"Running operations: %ld of %ld", active_and_pending_operations.count, count_of_operations);
JSCallbackOperation *op = [[JSCallbackOperation alloc] initWithItems:items callback:callback];
[op setQueuePriority:NSOperationQueuePriorityNormal];
[op setCompletionBlock:^{
NSLog(@"Operation completed.");
}];
[operationQueue addOperation:op];
}