与 WKWebView 相关的 iOS 7 崩溃

Posted

技术标签:

【中文标题】与 WKWebView 相关的 iOS 7 崩溃【英文标题】:iOS 7 crash related to WKWebView 【发布时间】:2015-03-24 13:46:44 【问题描述】:

我在 Crashlytics 中看到仅适用于 ios 7 的崩溃,我无法在模拟器上重现该崩溃。我有代码,如果 iOS 7 使用 UIWebView,如果 iOS 8 使用 WKWebView。它将第 67 行的崩溃显示为 EXC_BREAKPOINT UNKNOWN。

这是我的 viewDidLoad() 中的相关代码:

        if NSClassFromString("WKWebView") != nil 
            let config = WKWebViewConfiguration()
            wkWebView = WKWebView(frame: webView.frame, configuration: config)
            wkWebView!.navigationDelegate = self // line 67
            wkWebView!.loadRequest(urlRequest!)
            mainView.addSubview(wkWebView!)
            mainView.bringSubviewToFront(toolbar)
            let navBarHeight = self.navigationController?.navigationBar.frame.height
            let statusBarHeight = UIApplication.sharedApplication().statusBarFrame.size.height
            insets = UIEdgeInsetsMake(navBarHeight! + statusBarHeight, 0, toolbar.frame.size.height, 0)
            wkWebView!.scrollView.contentInset = insets
            wkWebView!.scrollView.scrollIndicatorInsets = insets
         else 
            webView.loadRequest(urlRequest!)
            insets = UIEdgeInsetsMake(0, 0, self.toolbar.frame.size.height, 0)
            webView.scrollView.contentInset = insets
            webView.scrollView.scrollIndicatorInsets = insets
        

由于是 iOS 7,我什至不明白它是如何进入 if 块的。

堆栈跟踪(第 85 行是 viewDidLoad 的右括号):

Thread : Crashed: com.apple.main-thread
0  ToC Festival                   0x0024afb4 ToC_Festival.WebViewController.viewDidLoad (ToC_Festival.WebViewController)() -> () (WebViewController.swift:85)
1  ToC Festival                   0x0024a5ec ToC_Festival.WebViewController.viewDidLoad (ToC_Festival.WebViewController)() -> () (WebViewController.swift:67)
2  UIKit                          0x32ef7a53 -[UIViewController loadViewIfRequired] + 518
3  UIKit                          0x32fa230d -[UINavigationController _layoutViewController:] + 32
4  UIKit                          0x32fa2223 -[UINavigationController _updateScrollViewFromViewController:toViewController:] + 230
5  UIKit                          0x32fa1801 -[UINavigationController _startTransition:fromViewController:toViewController:] + 80
6  UIKit                          0x32fa1529 -[UINavigationController _startDeferredTransitionIfNeeded:] + 572
7  UIKit                          0x32fa1299 -[UINavigationController __viewWillLayoutSubviews] + 44
8  UIKit                          0x32fa1231 -[UILayoutContainerView layoutSubviews] + 184
9  UIKit                          0x32ef3305 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 380
10 QuartzCore                     0x32b6f31b -[CALayer layoutSublayers] + 142
11 QuartzCore                     0x32b6ab3f CA::Layer::layout_if_needed(CA::Transaction*) + 350
12 QuartzCore                     0x32b6a9d1 CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 16
13 QuartzCore                     0x32b6a3e5 CA::Context::commit_transaction(CA::Transaction*) + 228
14 QuartzCore                     0x32b6a1f7 CA::Transaction::commit() + 314
15 QuartzCore                     0x32b63f1d CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 56
16 CoreFoundation                 0x3068f039 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 20
17 CoreFoundation                 0x3068c9c7 __CFRunLoopDoObservers + 286
18 CoreFoundation                 0x3068cd13 __CFRunLoopRun + 738
19 CoreFoundation                 0x305f7769 CFRunLoopRunSpecific + 524
20 CoreFoundation                 0x305f754b CFRunLoopRunInMode + 106
21 GraphicsServices               0x355646d3 GSEventRunModal + 138
22 UIKit                          0x32f56891 UIApplicationMain + 1136
23 ToC Festival                   0x001ae0d8 main (AppDelegate.swift:14)

另外,这是我在 WebViewController.swift 中为 UIWebView 和 WKWebView 实现委托方法的方式:

extension WebViewController: WKNavigationDelegate 
    func webView(webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) 
        activityIndicator.startAnimating()
    

    func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) 
        activityIndicator.stopAnimating()
    

    func webView(webView: WKWebView, didFailNavigation navigation: WKNavigation!, withError error: NSError) 
        activityIndicator.stopAnimating()
    


extension WebViewController: UIWebViewDelegate 
    func webViewDidStartLoad(webView: UIWebView!) 
        activityIndicator.startAnimating()
        //println("webViewDidStartLoad")
    

    func webViewDidFinishLoad(webView: UIWebView) 
        activityIndicator.stopAnimating()
        //println("webViewDidFinishLoad")
    

    func webView(webView: UIWebView!, didFailLoadWithError error: NSError!) 
        activityIndicator.stopAnimating()
        //println("An error occurred while loading the webview")
    

【问题讨论】:

你有崩溃的堆栈跟踪吗? 已更新堆栈跟踪。 尝试清理构建项目,看看问题是否仍然存在。 就像我说的,我无法重现这个问题。这发生在 Crashlytics 报告中。 【参考方案1】:

您遇到的是编译器中的一个错误 - NSClassFromString 在启用优化时不起作用。您可能正在 iOS 模拟器上运行调试版本,所以一切正常。尝试切换到 Release 配置,它应该会在模拟器中崩溃。

幸运的是,有一个解决方法 - objc_getClass 可用于优化,因此您可以将 if NSClassFromString("WKWebView") != nil 替换为 if objc_getClass("WKWebView") != nil

我已经写了一篇关于这个问题的博文 - https://febdev.wordpress.com/2015/01/22/swift-build-problems-in-release/

【讨论】:

以上是关于与 WKWebView 相关的 iOS 7 崩溃的主要内容,如果未能解决你的问题,请参考以下文章

iOS 10.3 WKWebView 访问照片库时崩溃

iOS 13 SceneDelegate 上的 WKWebView 警报崩溃

WKWebView runJavaScriptAlertPanelWithMessage 从 iOS 9.3 崩溃

由于 NSInvalidUnarchiveOperationException 导致 iOS11 WKWebview 崩溃

在 iOS14 上释放 wkwebview 时,发送手势事件导致崩溃

WKWebView 因某些查询而崩溃(iOS Swift)