2015-02-07 48 views
8

有什么办法从主线程同步查询JavaScript?WKWebView:试图从主线程同步查询JavaScript

func evaluateJavaScript(_ javaScriptString: String, completionHandler completionHandler: ((AnyObject!, NSError!) -> Void)?) 

异步行为通常可以接通同步用信号量暂停线程&控制执行:

JavaScript是从使用异步函数与回调参数以处理该响应的本地代码查询

// Executing in the main thread 
let sema = dispatch_semaphore_create(0) 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) { 
// Background thread 
    self.evaluateJavaScript("navigator.userAgent", completionHandler: { (value:AnyObject!, error: NSError!) -> Void in 
    if let ua = value as? String { 
     userAgent = ua 
    } else { 
     ERROR("ERROR There was an error retrieving the default user agent, using hardcoded value \(error)") 
    } 
    dispatch_semaphore_signal(sema) 
    }) 
} 
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER) 

...但是在这种情况下,因为completionHandler总是称为主线程,代码deadlo因为completionHandler块永远不会执行(主线程在最后一行被dispatch_semaphore_wait暂停)

有什么建议吗?

编辑

我宁愿不被阻塞主线程来执行代码。但是,如果不将我的API从同步改为异步,我就无法从主线程分离,并且在整个堆栈中产生多米诺骨牌效应(例如从let ua = computeUserAgent()computeUserAgent() {(ua: String)->Void in /*Use ua value here */})。所以我需要在两种方法之间进行选择,这两种方法都有缺点,我宁愿选择不会混淆我内部API的方法,特别是对于像查找用户代理一样微不足道的任务。

+0

当然,这里有一个建议:不要这样做。使用提供的功能并继续。不要试图颠覆异步功能。如果您阻止主线程等待,用户将无法与您的应用程序进行交互,并且看门狗进程可能会导致应用程序死机。有合法的方式让用户暂时无法做任何事情,但这不是其中之一。 – matt 2015-02-07 22:47:42

+0

@matt,我认为你在这里忽略了一点:据我了解,completionHandler似乎总是在主线程上运行,这使得很难实现evaluateJavascript调用的同步抽象化...同步不会意思是“在主线上” – 2015-02-07 23:53:51

+0

@StephanePhilipakis这不是他问的。他想要这个主线程(请参阅问题的标题)并且是同步的。他不应该那样想。我的评论说“不要那样”。 – matt 2015-02-08 00:06:57

回答

2

如果必须做到这一点...

正如评论建议this answer你可以运行在你的信号灯等待这样一个紧密的循环。

while (dispatch_semaphore_wait(sema, DISPATCH_TIME_NOW)) { 
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode 
          beforeDate:[NSDate dateWithTimeIntervalSinceNow:10]]; 
} 
+0

Kludgy,但它是一个工作答案,谢谢你的问题!还不太确定我将用于我的项目(特别是,@matt在问题的评论部分中提供了一些优点),但明天我会接受该答案,除非有更好的答案通过 – Hugo 2015-02-08 05:32:44

+0

您好。我测试了你的解决方案,它不工作。完成处理程序仍然被阻止,但仍然没有执行:/ – h3dkandi 2016-04-21 14:39:53

+0

它可能会导致崩溃! – Nikita 2016-12-15 12:31:08