iOS

Reason for crash caused by lazy loading of child objects when iOS parent object dealloc is triggered

Author : Lee
Published Time : 2025-11-04

One background

After the project went online, there was an occasional crash with the following crash stack. On the surface, the cause of the crash was accessing a lazily loaded object while dealing with the VC object, which triggered the creation of a weak reference to that object.


II analyze

Because this crash is occasional, after investigation, if the VC page has not called this object from initialization to about dealloc, and only accessed the lazy loading method of this object for the first time in dealloc, and this object happens to have a proxy or block callback that triggers the creation of a weak reference to the VC object, it will definitely trigger a crash.

For example, the following code:

When the lazy loading method of a child object is called for the first time during object dealloc, it will trigger the creation of a weak reference to that object and result in a crash.

//Test View
- (FJFLazyTestView *)testView {
    if (!_testView) {
        _testView = [[FJFLazyTestView alloc] init];
        _testView.delegate = self; //Collapse point
    }
    return _testView;
}

//Test View
- (FJFLazyTestView *)testView {
    if (!_testView) {
        _testView = [[FJFLazyTestView alloc] init];
        __weak typeof(self) weakSelf = self; ///Collapse point
        _testView.testBlock = ^{
            __strong typeof(weakSelf) strongSelf = weakSelf;
                if (!strongSelf) return; //Exit when the parent object has been destroyed
            [strongSelf testPrint];
        };
    }
    return _testView;
}

The direct cause of the crash: runtime security protection

If an attempt is made to create a new weak reference to the object during the deallic process (such as __weak typeof (self) weak Self=self):

  1. The storeWeak function checks whether the object is in a resolving state at runtime (marked by the objc_struct Instance function).
  2. When actively triggering a crash and detecting that an object is being deconstructed, storeWeak will call objc_data to throw the following crash log:
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)

The essence of a crash is proactive protection at runtime, preventing developers from accessing memory that is about to expire.

3、 governance

Change the child object in the object dealloc to an instance method to access something like _testView, or ensure that the lazy loading method of the child object has been called before the parent object dealloc.