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_915918412 小时前
移动端 HTTPS 抓包实战,多工具组合分析与高效排查指南
数据库·网络协议·ios·小程序·https·uni-app·iphone
Digitally3 小时前
解决“Move to iOS 卡在准备中”的 9 种有效方法
macos·ios·cocoa
5***79006 小时前
Swift进阶
开发语言·ios·swift
denggun123456 小时前
ios卡顿优化
ios·xcode
從南走到北6 小时前
JAVA国际版打车APP打车顺风车滴滴车跑腿APP源码Android+IOS+H5
android·java·ios
QuantumLeap丶8 小时前
《Flutter全栈开发实战指南:从零到高级》- 13 -状态管理GetX
android·flutter·ios·前端框架
從南走到北11 小时前
JAVA国际版二手车交易二手车市场系统源码支持Android+IOS+H5+APP
android·java·ios
ajassi200013 小时前
开源 Objective-C IOS 应用开发(九)复杂控件-tableview
ios·开源·objective-c
2501_9151063213 小时前
iOS性能调优的系统化实践,从架构分层到多工具协同的全流程优化指南(开发者深度版)
android·ios·小程序·架构·uni-app·iphone·webview
uiop_uiop_uiop13 小时前
iOS arm64e hook MGCopyAnswer got Crash or Only Partial results got hooked
macos·ios·cocoa