iOS 父对象dealloc时触发子对象懒加载导致出现崩溃原因探究和解决

一. 背景

项目上线后,偶现了一个崩溃,崩溃堆栈如下,从表面看崩溃的原因是在vc对象dealloc的时候,访问了一个懒加载的对象,这时候触发了该对象的弱引用创建。

二. 分析

因为这个崩溃是偶现的,经排查下来,如果VC页面从初始化到即将dealloc,都没有调用过这个对象,只在dealloc访问了首次这个对象的懒加载方法,而这个对象刚好有代理或者block回调,触发了VC对象的弱引用的创建,就一定会触发崩溃。

例如如下代码:

在对象dealloc的时候,首次调用子对象的懒加载方法,都会触发该对象的弱引用的创建,都会触发崩溃。

ini 复制代码
// 测试视图
- (FJFLazyTestView *)testView {
    if (!_testView) {
        _testView = [[FJFLazyTestView alloc] init];
        _testView.delegate = self; /// 崩溃点
    }
    return _testView;
}

// 测试视图
- (FJFLazyTestView *)testView {
    if (!_testView) {
        _testView = [[FJFLazyTestView alloc] init];
        __weak typeof(self) weakSelf = self; // 崩溃点
        _testView.testBlock = ^{
            __strong typeof(weakSelf) strongSelf = weakSelf;
                if (!strongSelf) return; // 父对象已销毁时退出
            [strongSelf testPrint];
        };
    }
    return _testView;
}

崩溃的直接原因:运行时安全防护

若在 对象dealloc 过程中尝试创建新的该对象弱引用(如 __weak typeof(self) weakSelf = self):

  1. 运行时检查对象状态 storeWeak 函数会检测对象是否处于 deallocating 状态(通过 objc_destructInstance 函数标记)。
  2. 主动触发崩溃 当检测到对象正在析构时,storeWeak 会调用 objc_fatal 抛出以下崩溃日志:
scss 复制代码
if (deallocating) {
    _objc_fatal("Cannot form weak reference to instance (%p) of class %s. 
                It is possible that this object was over-released, 
                or is in the process of deallocation.", 
                (void*)referent, object_getClassName((id)referent));
} // [2](@ref)

崩溃本质是运行时的主动防护,防止开发者访问即将失效的内存。

三. 治理

将对象dealloc里面的将子对象改为实例方法访问类似_testView这样的,或者确保父对象dealloc之前,一定调用过子对象的懒加载方法。

相关推荐
Dolphin_海豚7 小时前
charles proxying iphone
前端·ios
Magnetic_h11 小时前
【iOS】内存管理及部分Runtime复习
笔记·学习·macos·ios·objective-c·cocoa·xcode
jiushiapwojdap1 天前
Flutter上手记:为什么我的按钮能同时在iOS和Android上跳舞?[特殊字符][特殊字符]
android·其他·flutter·ios
yede1 天前
uniapp - 配置iOS的Universal Links
ios·uni-app
Andy_GF1 天前
鸿蒙Next在蒲公英平台分发测试包
android·ios·harmonyos
zkmall1 天前
ZKmall开源商城多端兼容实践:鸿蒙、iOS、安卓全平台适配的技术路径
ios·开源·harmonyos
海的天空16612 天前
Flutter旧版本升级-> Android 配置、iOS配置
android·flutter·ios
kymjs张涛2 天前
零一开源|前沿技术周刊 #13
ios·harmonyos·apple
源码哥_博纳软云3 天前
JAVA国际版多商户运营版商城系统源码多商户社交电商系统源码支持Android+IOS+H5
android·java·ios·微信·微信小程序·小程序·uni-app
2501_915106323 天前
iOS混淆工具实战 金融支付类 App 的安全防护与合规落地
android·ios·小程序·https·uni-app·iphone·webview