我有一个使用JavaScriptCore的UIWebView。我正试图从网页上调用一个ObjC函数。但是,函数需要异步调用,所以我传入一个在调用异步ObjC函数时调用的回调函数。
据我所知,JS函数通过桥接器等效于NSBlock。我目前的代码是:
context[@"currentUserLocation"] = ^( void(^callback)(NSString* str) )
{
NSLog(@"Starting Async Function");
//generic async function
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"delay complete");
callback( @"return value" );
});
};
我正在做的事情是否存在根本性的错误?从表面上看,ObjC似乎不知道运行回调函数的上下文。
答案 0 :(得分:1)
我花了一点时间来解决这个问题。诀窍不是将回调参数视为块,而是将JSValue视为使用JSValue API调用它:
context[@"currentUserLocation"] = ^(JSValue *callback)
{
NSLog(@"Starting Async Function");
//generic async function
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"delay complete");
//Check we actually have a callback (isObject is the best we can do, there is no isFunction)
if ([callback isObject] != NO) {
//Use window.setTimeout to schedule the callback to be run
[context[@"setTimeout"] callWithArguments:@[callback, @0, @"return value"]];
}
});
};
在window.setTimeout()调用中包装回调允许JSVirtualMachine处理调度和线程,我发现如果回调完成任何UI工作,直接调用回调通常会导致死锁。