iOS WebView WTF 崩溃
iOS WebView WTF crash
有人遇到下面的崩溃吗?
0 WebKitLegacy 0x000000018f766884 std::__1::unique_ptr<WTF::Function<void ()>, std::__1::default_delete<WTF::Function<void ()> > > WTF::MessageQueue<WTF::Function<void ()> >::waitForMessageFilteredWithTimeout<WTF::MessageQueue<WTF::Function<void ()> >::waitForMessage()::'lambda'(WTF::Function<void ()> const&)>(WTF::MessageQueueWaitResult&, WTF::MessageQueue<WTF::Function<void ()> >::waitForMessage()::'lambda'(WTF::Function<void ()> const&)&&, double) + 192
1 WebKitLegacy 0x000000018f765e68 WebCore::StorageThread::threadEntryPoint() + 68
5 JavaScriptCore 0x000000018dabf35c WTF::threadEntryPoint(void*) + 212
6 JavaScriptCore 0x000000018dabf26c WTF::wtfThreadEntryPoint(void*) + 24
8 libsystem_pthread.dylib 0x0000000188c9f860 __pthread_body + 240
9 libsystem_pthread.dylib 0x0000000188c9f770 __pthread_body
10 libsystem_pthread.dylib 0x0000000188c9cdbc start_wqthread + 0
停止加载 webView
并在离开视图之前删除 delegate
。
Before releasing an instance of UIWebView for which you have set a
delegate, you must first set its delegate property to nil. This can be
done, in your dealloc method.
尝试将 WebView
的委托设置为 nil
并停止在 ViewController 的 viewWillUnload
方法中加载 WebView:
- (void)viewWillUnload {
[webView setDelegate:nil];
[webView stopLoading];
}
最后,我发现这个崩溃与localstorage线程有关。当我们在JavaScript中调用window.localStorage时,会触发webkit创建一个localstorage线程,当所有的UIWebView实例dealloc时,该线程会被销毁。事实上,localstorage 线程会比 UIWebView 实例更晚被销毁,这会导致野指针崩溃。因此,您可以创建一个执行 "window.localstorage.setItem(x,x)" 并且从不销毁它的 UIWebView 实例,或者您可以使用 WKWebView.
我已经通过创建静态 UIWebView 实例解决了这个问题。
+ (void)load {
if ([UIDevice isIOS10]) {
static UIWebView *storageCrashFixWebView = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
storageCrashFixWebView = [[UIWebView alloc] initWithFrame:CGRectZero];
[storageCrashFixWebView loadHTMLString:@"<script>window.localStorage</script>" baseURL:nil];
});
}
}
当我在 std::__1::unique_ptr<WTF::Function<void ()>, std::__1::default_delete<WTF::Function<void ()> > > WTF::MessageQueue<WTF::Function<void ()> >::waitForMessageFilteredWithTimeout<WTF::MessageQueue<WTF::Function<void ()> >::waitForMessage()::'lambda'(WTF::Function<void ()> const&)>(WTF::MessageQueueWaitResult&, WTF::MessageQueue<WTF::Function<void ()> >::waitForMessage()::'lambda'(WTF::Function<void ()> const&)&&, double)
设置符号断点时,它会在最后一个使用 localStorage
的 UIWebView 被销毁时中断。
有人遇到下面的崩溃吗?
0 WebKitLegacy 0x000000018f766884 std::__1::unique_ptr<WTF::Function<void ()>, std::__1::default_delete<WTF::Function<void ()> > > WTF::MessageQueue<WTF::Function<void ()> >::waitForMessageFilteredWithTimeout<WTF::MessageQueue<WTF::Function<void ()> >::waitForMessage()::'lambda'(WTF::Function<void ()> const&)>(WTF::MessageQueueWaitResult&, WTF::MessageQueue<WTF::Function<void ()> >::waitForMessage()::'lambda'(WTF::Function<void ()> const&)&&, double) + 192
1 WebKitLegacy 0x000000018f765e68 WebCore::StorageThread::threadEntryPoint() + 68
5 JavaScriptCore 0x000000018dabf35c WTF::threadEntryPoint(void*) + 212
6 JavaScriptCore 0x000000018dabf26c WTF::wtfThreadEntryPoint(void*) + 24
8 libsystem_pthread.dylib 0x0000000188c9f860 __pthread_body + 240
9 libsystem_pthread.dylib 0x0000000188c9f770 __pthread_body
10 libsystem_pthread.dylib 0x0000000188c9cdbc start_wqthread + 0
停止加载 webView
并在离开视图之前删除 delegate
。
Before releasing an instance of UIWebView for which you have set a delegate, you must first set its delegate property to nil. This can be done, in your dealloc method.
尝试将 WebView
的委托设置为 nil
并停止在 ViewController 的 viewWillUnload
方法中加载 WebView:
- (void)viewWillUnload {
[webView setDelegate:nil];
[webView stopLoading];
}
最后,我发现这个崩溃与localstorage线程有关。当我们在JavaScript中调用window.localStorage时,会触发webkit创建一个localstorage线程,当所有的UIWebView实例dealloc时,该线程会被销毁。事实上,localstorage 线程会比 UIWebView 实例更晚被销毁,这会导致野指针崩溃。因此,您可以创建一个执行 "window.localstorage.setItem(x,x)" 并且从不销毁它的 UIWebView 实例,或者您可以使用 WKWebView.
我已经通过创建静态 UIWebView 实例解决了这个问题。
+ (void)load {
if ([UIDevice isIOS10]) {
static UIWebView *storageCrashFixWebView = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
storageCrashFixWebView = [[UIWebView alloc] initWithFrame:CGRectZero];
[storageCrashFixWebView loadHTMLString:@"<script>window.localStorage</script>" baseURL:nil];
});
}
}
当我在 std::__1::unique_ptr<WTF::Function<void ()>, std::__1::default_delete<WTF::Function<void ()> > > WTF::MessageQueue<WTF::Function<void ()> >::waitForMessageFilteredWithTimeout<WTF::MessageQueue<WTF::Function<void ()> >::waitForMessage()::'lambda'(WTF::Function<void ()> const&)>(WTF::MessageQueueWaitResult&, WTF::MessageQueue<WTF::Function<void ()> >::waitForMessage()::'lambda'(WTF::Function<void ()> const&)&&, double)
设置符号断点时,它会在最后一个使用 localStorage
的 UIWebView 被销毁时中断。