iOS 11.3/11.4中UIWebView崩溃问题技术求助
我经手过好几起类似的混合应用崩溃案例,结合你给出的崩溃堆栈和场景(搭载UIWebView的iOS应用,加载含大量追踪像素、异步JS的电商页面),这个问题的根源和解决思路可以这样梳理:
问题根源分析
从崩溃堆栈来看:
Crashed: WebThread
0 WebCore 0x18b7b0d98 WebCore::Page::sessionID() const + 16
1 WebKitLegacy 0x18be91204 WebFrameNetworkingContext::storageSession() const + 24
2 WebCore 0x18ad818bc WebCore::ResourceHandle::willSendRequ...
崩溃发生在WebThread上,是当网络请求(ResourceHandle)准备发送时,尝试获取页面的存储会话(storageSession),而会话依赖的Page对象已经被释放,导致空指针访问sessionID()触发崩溃。
iOS 11.3对WebKit的会话管理逻辑做了更新,而你的页面有大量异步请求(追踪像素、异步JS),这些请求会在WebThread后台持续触发,一旦UIWebView的页面上下文因为生命周期变化(比如页面跳转、视图销毁)被部分释放,异步请求就会访问已失效的Page对象,进而引发崩溃。
可行的解决方案
1. 长期根治:迁移到WKWebView
苹果从iOS 11开始就逐步停止UIWebView的维护,WKWebView采用了更独立的进程模型和更稳定的资源管理机制,从根源上避免这类WebThread崩溃。迁移时需要注意几个适配点:
- 用
WKWebViewConfiguration的websiteDataStore管理会话和Cookie,确保和原UIWebView的Cookie共享逻辑一致; - 调整JS交互逻辑,改用
WKScriptMessageHandler替代原UIWebView的stringByEvaluatingJavaScriptFromString:; - 处理WKWebView的加载回调,确保异步请求的生命周期和WebView绑定更合理。
2. 临时应急修复(无法立即迁移时)
- 严格管理UIWebView生命周期:在WebView即将被销毁时(比如
viewWillDisappear),先调用[webView stopLoading]终止所有正在进行的网络请求,然后置空webView.delegate,避免异步回调触发已释放的上下文; - 优化页面异步请求:和前端团队配合,合并冗余的追踪像素请求,延迟非核心异步JS的执行时机,减少WebThread的并发压力;
- 测试系统版本覆盖:iOS 11.3早期版本存在WebKit的会话管理bug,测试iOS 11.4及以上版本,看崩溃是否自然消失,同时引导用户升级系统。
3. 兜底处理
虽然Objective-C无法直接捕获WebCore的C++异常,但可以通过NSSetUncaughtExceptionHandler注册全局异常捕获器,在崩溃发生时做日志上报和优雅退出,不过这只能缓解用户体验问题,无法根治崩溃。
内容的提问来源于stack exchange,提问作者msung

