【问题标题】:iOS: [CFRunLoopTimer release]: message sent to deallocated instance Error debugiOS: [CFRunLoopTimer release]: message sent to deallocated instance Error debug
【发布时间】:2014-04-19 10:20:22
【问题描述】:

我正在开发一个 iOS 应用程序 (iOS 7)

我在 UiWebView 上多次执行 Javascript

但很多次(随机)

****我得到这个崩溃错误 [CFRunLoopTimer release]:消息发送到释放的实例

**** 有时 像这样的错误:**** **webthread 不允许多线程锁******

我已确保一次只有一个线程对 UIWebview 执行操作

我尝试在每个线程和队列(后台线程、主线程和不同的全局队列)上执行操作(但没有成功)

在分析应用程序并在 Instruments 上重现崩溃时(僵尸模式) 我收到这条消息

我已经彻底检查了我的 javascript(100% 正确)。

但我仍然多次收到此错误。

谁能告诉我如何解决这个问题 调试此错误的任何解决方案或任何提示。 (我已经设置了 NSZombienabled = YES )但这也无济于事。

【问题讨论】:

  • 在 XCode 中使用分析器它会为您显示不正确的版本
  • “不允许 webthread 多线程锁”表明您可能正在后台线程上执行一些 UI 工作。检查与后台线程或完成处理程序相关的所有代码,并确保在主线程上调用任何 UI 代码。

标签: javascript ios uiwebview


【解决方案1】:

我也被这个完全相同的错误困扰了很长一段时间了。

就像你一样,我尝试了几乎所有的东西,从 NSOperationQueue 的 addOperationWithBlock:dispatch_asyncperformSelectorOnMainThread:withObject:waitUntilDone:...(当然是在黑暗中拍摄)

然后我发现我总是使用 [myJsContext evaluateScript:jsString]; 调用我的 js 代码,并使用 [myWebView valueForKeyPath: @"documentView.webView.mainFrame.javaScriptContext"]; 从 UIWebView 获取 JSContext。

相反,我尝试了旧的[myWebView stringByEvaluatingJavaScriptFromString:jsString];,现在它似乎可以工作了(至少它已经很久没有崩溃了)。

所以也许这是一个解决方案,因为您也在使用 UIWebViews?我的理解是evaluateScript: 在您使用没有 UIWebView 的 JSContext 时特别有用。

(这个答案可能缺乏实际的技术确定性,所以如果您对 JavaScriptCore 有更多了解,请深入了解......但是,嘿,它似乎对我有用!)

【讨论】:

    【解决方案2】:

    我已经解决了这个崩溃问题,只需在 UIWebView 上调用一个虚拟 stringByEvaluatingJavaScriptFromString,然后再调用上下文中的方法。我相信这个工作的原因是对 javascript 的调用是在 Web 线程上完成的,它使用一个计时器来接收返回给主线程的回复,当调用调用时,这个计时器没有被创建,所以当回复从 Web 返回时线程在尝试释放一个从未创建过的计时器时崩溃。通过使用适当的 API stringByEvaluatingJavaScriptFromString in 确保创建计时器,然后 invokeMethod 可以使用相同的计时器。

    JSContext* context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    JSValue* value = context[@"Colors"];
    
    // timer CFRelease crash fix
    [webView stringByEvaluatingJavaScriptFromString:nil]; 
    
    [value invokeMethod:@"update" withArguments:@[objectID,modifier]];
    

    【讨论】:

      【解决方案3】:

      我建议您在项目中找到所有 NSTimer 并查看某个对象是否两次释放它。因此,您可以在每个释放计时器的方法上设置断点,并查看某个方法何时调用此释放。

      第二个建议是: 使用分析器分配所有对象,当然还要激活 NSZombie。

      【讨论】:

      • 也许你用的是第三个库?
      • 我正在分析我的应用程序。你能告诉我在分析时应该关注哪个“领域”
      【解决方案4】:

      您应该只从主线程调用 UIWebView 上的方法。 UIWebView 不是线程安全的,从多个线程调用方法是不安全的。

      您说“我已确保一次只有一个线程对 UIWebview 执行操作”:不幸的是,这还不够。因为:您不是唯一一个在网络视图上拨打电话的人。有运行循环计时器。有用户触摸 webview。还有其他事情正在发生。

      【讨论】:

      • @Micheal 你能告诉我,当我在 MainThread 上的 UiWebView 上调用我的方法时,我如何确保另一个线程没有在 UIWebView 上执行操作,并且它在没有给出任何响应或调用委托方法的情况下崩溃。
      • 根据 WWDC 2013 视频,从 UIWebView 检索到的 JSContext 是线程安全的。但是 Dinesh 无论如何都在使用主线程。
      猜你喜欢
      • 1970-01-01
      • 2011-07-02
      • 1970-01-01
      • 1970-01-01
      • 2012-08-11
      • 2013-07-03
      • 2012-11-17
      • 1970-01-01
      相关资源
      最近更新 更多