我正在开发iOS应用程序(iOS 7)
我多次在UiWebView上执行Javascript
但很多次(随机)
****我的错误导致此崩溃 [CFRunLoopTimer release]:发送到解除分配的实例的消息
****,有时候 像这样的错误:**** **不允许使用webthread多线程锁******
我确保一次只有一个线程在UIWebview上执行操作
我试图在每个线程和队列(后台线程,主线程和不同的全局队列)上执行操作(但没有成功)
在分析应用程序并重现仪器崩溃时(僵尸模式) 我收到这条消息
我已经彻底检查了我的javascript(100%正确)。
但我仍然多次犯这个错误。
任何人都可以告诉我如何解决这个问题 用于调试此错误的任何解决方案或任何提示。 (我已经设置了NSZombienabled = YES),但这也无济于事。
答案 0 :(得分:2)
我已经被这个完全相同的错误困住了很长一段时间。
就像你一样,我尝试了很多东西,从NSOperationQueue的addOperationWithBlock:
到dispatch_async
到performSelectorOnMainThread:withObject:waitUntilDone:
......(诚然在黑暗中拍摄)
然后我想我总是使用[myJsContext evaluateScript:jsString];
调用我的js代码,并使用[myWebView valueForKeyPath: @"documentView.webView.mainFrame.javaScriptContext"];
从UIWebView获取JSContext。
相反,我尝试了较旧的[myWebView stringByEvaluatingJavaScriptFromString:jsString];
,现在似乎工作了(至少它在很长一段时间没有崩溃)。
所以也许这是一个解决方案,因为你也在使用UIWebViews?我的理解是,如果您使用没有UIWebView的JSContext,evaluateScript:
特别有用。
(这个答案可能缺乏实际的技术确定性,所以如果你对JavaScriptCore有更多了解,请深入了解......但是,嘿,它似乎对我有用!)
答案 1 :(得分:1)
我认为这个崩溃了,只需在UIWebView上调用一个虚拟的stringByEvaluatingJavaScriptFromString,然后再调用上下文中的方法。我相信这个工作的原因是调用javascript是在Web Thread上完成的,它使用一个计时器来接收回复给主线程的回复,当调用invoke这个计时器没有被创建时所以当回复从Web返回时线程崩溃尝试释放从未创建过的计时器。通过使用适当的API stringByEvaluatingJavaScriptFromString确保创建计时器,然后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]];
答案 2 :(得分:-1)
我建议您在项目中找到所有NSTimer,并查看某个对象是否释放了两次。因此,您可以在释放计时器的每个方法上设置断点,并在某个方法调用此版本时查看。
第二个建议是: 使用探查器分配所有对象,当然也可以激活NSZombie。
答案 3 :(得分:-1)
您应该只从主线程调用UIWebView上的方法。 UIWebView不是线程安全的,并且从多个线程调用方法是不安全的。
你说"我确保一次只有一个线程在UIWebview上执行操作":不幸的是,这还不够。因为:您不是唯一一个在Web视图上进行调用的人。有runloop计时器。有用户触摸webview。其他的东西正在发生。