You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复Cordova应用在iOS 16.1上崩溃的问题?

iOS 16.1下Cordova子视图控制器添加崩溃问题

我正在开发一款iOS平台的Cordova应用,仅在iOS 16.1系统上会崩溃。我通过以下Swift代码将Cordova的CDViewController子类(SampleController)的WebView作为子视图添加到当前视图控制器中:

// SampleViewController是CDViewController的子类。
if let tempWidgetVC =  storyboard.instantiateViewController(withIdentifier: "SampleController") as? SampleController {
    tempWidgetVC.view.frame = CGRect(x: 0, y: 135, width: self.view.frame.size.width, height: self.view.frame.size.height - 150)
    self.view.addSubview(tempWidgetVC.webView)
}

这段代码在API调用完成后执行时会引发崩溃,但在viewDidLoad或viewDidAppear中执行却完全正常。崩溃日志如下:

thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xfffffffffffffff0)
frame #0: 0x0000000117237c04 WebKitWebKit::WebUserContentControllerProxy::removeUserMessageHandlerForName(WTF::String const&, API::ContentWorld&) + 804 frame #1: 0x0000000116ed2a54 WebKit-[WKUserContentController removeScriptMessageHandlerForName:] + 52
frame #2: 0x0000000111e350fe BlackBerryDynamics___lldb_unnamed_symbol7713 + 267 frame #3: 0x000000011719ab7f WebKitWebKit::WebProcessPool::~WebProcessPool() + 2569
frame #4: 0x0000000116ecf9a1 WebKit-[WKProcessPool dealloc] + 48 frame #5: 0x00007ff80004b6b1 libobjc.A.dylibobjc_object::sidetable_release(bool, bool) + 203
frame #6: 0x00000001171a4b43 WebKitWebKit::WebProcessProxy::~WebProcessProxy() + 2389 frame #7: 0x00000001171a4c4e WebKitWebKit::WebProcessProxy::~WebProcessProxy() + 14
frame #8: 0x0000000116cdf39d WebKitWTF::ThreadSafeRefCounted<WebKit::AuxiliaryProcessProxy, (WTF::DestructionThread)2>::deref() const + 67 frame #9: 0x00000001171afb38 WebKitWTF::Detail::CallableWrapper<WebKit::WebPageProxy::close()::$_13, void>::~CallableWrapper() + 136
frame #10: 0x00000001140878f8 JavaScriptCoreWTF::RunLoop::performWork() + 440 frame #11: 0x00000001140881da JavaScriptCoreWTF::RunLoop::performWork(void*) + 26
frame #12: 0x00007ff800387035 CoreFoundation__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17 frame #13: 0x00007ff800386f74 CoreFoundation__CFRunLoopDoSource0 + 157
frame #14: 0x00007ff800386771 CoreFoundation__CFRunLoopDoSources0 + 212 frame #15: 0x00007ff800380e73 CoreFoundation__CFRunLoopRun + 927
frame #16: 0x00007ff8003806f7 CoreFoundationCFRunLoopRunSpecific + 560 frame #17: 0x00007ff809c5c28a GraphicsServicesGSEventRunModal + 139
frame #18: 0x000000011f36562b UIKitCore-[UIApplication _run] + 994 frame #19: 0x000000011f36a547 UIKitCoreUIApplicationMain + 123
frame #20: 0x00000001109e2c72 libswiftUIKit.dylibUIKit.UIApplicationMain(Swift.Int32, Swift.Optional<Swift.UnsafeMutablePointer<Swift.UnsafeMutablePointer<Swift.Int8>>>, Swift.Optional<Swift.String>, Swift.Optional<Swift.String>) -> Swift.Int32 + 98 frame #21: 0x000000010f805c55 OCPMobilemain [inlined] generic specialization <App.AppDelegate> of static __C.UIApplicationDelegate.main() -> () at UserDefaultsHelper.swift:0 [opt]
frame #22: 0x000000010f805c05 OCPMobilemain [inlined] static OCPMobile.AppDelegate.$main() -> () at <compiler-generated>:11:1 [opt] frame #23: 0x000000010f805bf4 OCPMobilemain at UserDefaultsHelper.swift:0 [opt]
frame #24: 0x000000010ffeb2bf dyld_simstart_sim + 10 frame #25: 0x0000000113f8852e dyldstart + 462


问题根源

崩溃日志指向WebKit尝试访问已销毁的对象(EXC_BAD_ACCESS),核心原因是:API回调执行完后,tempWidgetVC作为临时变量被ARC自动释放,但其关联的WebKit资源(WKProcessPool、WKUserContentController等)还在后台处理操作,导致访问已释放内存。

而viewDidLoad/viewDidAppear中正常是因为控制器生命周期阶段的ARC引用时机特殊,临时变量的生命周期被意外延长,属于侥幸情况,并非正确实现。

解决方案

  1. 持有子控制器的强引用
    在当前视图控制器中添加属性,保留SampleController实例,避免被ARC回收:
// 在当前控制器类中声明强引用属性
var widgetVC: SampleController?

// API回调中执行的代码
if let tempWidgetVC = storyboard.instantiateViewController(withIdentifier: "SampleController") as? SampleController {
    tempWidgetVC.view.frame = CGRect(x: 0, y: 135, width: self.view.frame.size.width, height: self.view.frame.size.height - 150)
    // 正确建立父子控制器关系
    self.addChild(tempWidgetVC)
    self.view.addSubview(tempWidgetVC.webView)
    tempWidgetVC.didMove(toParent: self)
    // 持有引用
    self.widgetVC = tempWidgetVC
}
  1. 遵循UIViewController生命周期规范
    Cordova的CDViewController依赖完整的控制器生命周期,直接添加webView会跳过viewWillAppear、didMoveToParent等关键方法,导致WebKit资源初始化/销毁流程异常,必须通过addChild和didMove(toParent:)完成父子关系绑定。

  2. 适配iOS 16.1的严格内存检查
    iOS 16.1对WebKit的内存管理做了更严格的校验,之前版本未触发的内存问题在该版本暴露,确保所有WebKit相关的控制器和资源都有完整的引用链。


内容的提问来源于stack exchange,提问作者suraj Gupta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 02:15:35