我有一个利用JavaScriptCore的UIWebView.我正在尝试从网页调用ObjC函数.但是,该函数需要异步调用,因此我传递了一个在调用异步ObjC函数时调用的回调函数.
I have a UIWebView that utilizes JavaScriptCore. I'm trying to call an ObjC function from an web page. However, the function needs to be call asynchronously, so I'm passing in a callback function that is called when the async ObjC function is called.
据我了解,JS函数通过桥等效于NSBlock.我当前拥有的代码是:
It is my understanding that JS functions are equivalent to NSBlock via the bridge. The current code I have is:
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似乎不知道在哪个上下文中运行回调函数.
Is there something fundamentally wrong with what I'm doing? On the surface it seems like ObjC won't know what context to run the callback function in.
推荐答案花了我一些时间才能解决这个问题.诀窍不是将回调参数视为一个块,而是一个JSValue,然后使用JSValue API对其进行调用:
It took me a little while to get the hang of this. The trick is not to think of the callback argument as a block, but a JSValue and then call it using the 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工作,直接调用回调通常会导致死锁.
Wrapping the callback in a window.setTimeout() call allows the JSVirtualMachine to take care of scheduling and threading, I have found calling the callback directly often leads to deadlocks if any UI work is done by the callback.
更多推荐
JavaScriptCore
发布评论