Search code examples
iosobjective-cautomatic-ref-countingweak-references

Why __weak object will be added to autorelease pool?


id __weak obj1 = obj0;

equals

id __weak obj1 = obj0;
id __autoreleasing tmp = obj0;

In Pro multithreading and memory management for iOS and OSX.

But why the obj1 need to add to the autorelease pool, I think making a weak pointer of an object should not affect its lifetime.


Solution

  • {
        NSObject* sp = [NSObject new];
        NSObject* __weak wp = sp;
    }
    

    the above code is translate to:

    id sp = objc_msgSend(NSObject, "new");
    id wp;
    objc_initWeak(&wp, sp);
    objc_destroyWeak(&wp);
    objc_storeStrong(&sp, 0);
    

    1) obj_initWeak merely associate the weak pointer wp with the strong pointer sp to ensure that when the object pointed by sp is dealloced wp would auto reset to nil, which would not intecrement the retain count of the pointed object.
    2)obj_destroyWeak destroy the association of the weak pointer and strong pointer.
    3)obj_storeStrong in the last statement equal to [sp release].

    But as soon as we use the weak pointer, the compiler would generate a new reference for the object pointed.

    {
        NSObject* sp = [NSObject new];
        NSObject* __weak wp = sp;
        NSLog(@"%@", wp);
    }
    

    becomes

    id sp = objc_msgSend(NSObject, "new");
    id wp;
    objc_initWeak(&wp, sp);
    id tmp = objc_loadWeakRetained(wp);
    NSLog(@"%@", wp);
    objc_release(tmp);
    objc_destroyWeak(&wp);
    objc_storeStrong(&sp, 0);
    

    objc_loadWeakRetained would increment the reference count to ensure that tmp is alive in the NSLog statement. objc_release reset the object to the original state.

    In conclusion, this design of __weak ensure that during the usage of weak pointer, its state is consistent. The new implmenetation of __weak of Apple LLVM version 8.0.0 (clang-800.0.42.1) do not postpond the release to autoreleasepool, but use objc_release directly.