为什么 __weak 对象会被添加到自动释放池?

Why __weak object will be added to autorelease pool?

id __weak obj1 = obj0;

等于

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

iOS 和 OSX 的 Pro 多线程和内存管理中。

但是为什么obj1需要添加到自动释放池中,我认为做一个对象的弱指针应该不会影响它的生命周期。

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

以上代码翻译为:

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

1) obj_initWeak只是将弱指针wp与强指针sp关联起来,确保sp指向的对象被释放时wp 会自动重置为 nil,这不会增加指向对象的保留计数。
2)obj_destroyWeak破坏弱指针与强指针的关联
3)最后一个语句中的obj_storeStrong等于[sp release].

但是一旦我们使用弱指针,编译器就会为指向的对象生成一个新的引用。

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

变成

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 会增加引用计数以确保 tmpNSLog 语句中处于活动状态。 objc_release 将对象重置为原始状态。

综上所述,__weak的这种设计保证了弱指针在使用过程中,其状态是一致的。 Apple LLVM version 8.0.0 (clang-800.0.42.1)__weak的新实现没有延迟发布到autoreleasepool,而是直接使用objc_release