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之前,一定调用过子对象的懒加载方法。

相关推荐
2501_9151063232 分钟前
第一次开发 iPhone App,可能碰到的问题,解决办法
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
2501_915106321 小时前
iOS数据采集技术详解:从性能监控到崩溃分析的全链路实践
android·ios·小程序·https·uni-app·iphone·webview
末代iOS程序员华仔16 小时前
iOS 5.6 条例解决方法
flutter·ios·swift
末代iOS程序员华仔1 天前
Guideline 5.6 - Developer Code of Conduct
flutter·ios·swift
2501_915918411 天前
Flutter项目配置iOS混淆的详细步骤与工具推荐
android·flutter·ios·小程序·uni-app·cocoa·iphone
凡泰AI1 天前
如何通过小程序多端框架,让一个小程序同时运行在iOS、安卓、鸿蒙和微信客户端,实现开发层面的降本增效
android·ios·微信小程序·小程序·harmonyos
2501_915106322 天前
安卓抓包软件2026,免证书抓包 应用层抓包 代理抓包全解析
网络协议·计算机网络·网络安全·ios·adb·https·udp
kango2 天前
Xcode、模拟器Runtime、真机符号完整知识手册
ios·app
用户38034165882972 天前
50MB 红线下的 iOS 录屏引擎:ReplayKit Broadcast Extension 实战
ios
Privasa-隐私实验室2 天前
跨端技术选型|Flutter搭建隐私加密App,安卓与iOS双端差异适配实战
android·笔记·安全·flutter·ios·隐私安全·aes-256