__weak relies on the Objective-C runtime function objc_loadWeak. From Objective-C Automatic Reference Counting in the documentation for Clang 3.4:
id objc_loadWeak(id *object);
Precondition: object is a valid pointer which either contains a null
pointer or has been registered as a __weak object.
If object is registered as a __weak object, and the last value stored
into object has not yet been deallocated or begun deallocation,
retains and autoreleases that value and returns it. Otherwise returns
null. Equivalent to the following code:
id objc_loadWeak(id *object) {
return objc_autorelease(objc_loadWeakRetained(object));
}
Must be atomic with respect to calls to objc_storeWeak on object.
Rationale
Loading weak references would be inherently prone to race
conditions without the retain.
Since objc_loadWeak requires an autorelease pool, then you must have an autorelease pool present when using __weak. The pool can created by either NSAutoreleasePool or @autoreleasepool. If an autorelease pool is not present, then nothing will release your object after objc_loadWeak retains it and your object will therefore never be deallocated.
Here is a fix for the code above:
#import <Foundation/Foundation.h>
@interface MyObj : NSObject
@end
@implementation MyObj
- (void)dealloc
{
NSLog(@"MyObj dealloc'd %p", self);
}
@end
int main(int argc, const char * argv[])
{
@autoreleasepool {
MyObj* obj1 = [[MyObj alloc] init];
__weak MyObj* weakObj1 = obj1;
NSLog(@"Use it: %p\n", weakObj1);
// Now MyObj is deallocated
}
return 0;
}