I am reading Pro Multithreading and Memory Management for iOS and OS X with ARC, Grand Central Dispatch, and Blocks written by Kazuki Sakamoto.
The book wrote:
When a variable with a __weak qualifier is used, the object is always registered in autoreleasepool.
id __weak obj1 = obj0; NSLog(@"class=%@", [obj1 class]);
The above source code is equivalent to:
id __weak obj1 = obj0; id __autoreleasing tmp = obj1; NSLog(@"class=%@", [tmp class]);
Why does the object need to be registered in autoreleasepool in order to use the object via the __weak qualified variable? Because a variable, which is qualified with __weak, does not have a strong reference, the object might be disposed of at any point. If the object is registered in autoreleasepool, until @autoreleasepool block is left, the object must exist. So, to use the objects via __weak variable safely, the object is registered in autoreleasepool automatically.
I have given below the program to verify what the author wrote.
@interface A : NSObject
- (void) dealloc;
@end
@implementation A
- (void) dealloc
{
NSLog(@"dealloc");
}
@end
int main()
{
@autoreleasepool
{
{
A *obj0 = [[A alloc] init];
id __weak obj1 = obj0;
NSLog(@"end of block");
}
NSLog(@"end of autoreleasepool");
}
return(0);
}
Actual Output:
end of block
dealloc
end of autoreleasepool
Expected Output:
end of block
end of autoreleasepool
dealloc
obj1 is disposed at the end of the block. It's obvious that obj1 isn't registered in autoreleasepool automatically.
If I manually add
id __autoreleasing tmp = obj1;
The output is expected. obj1 is disposed at the end of the autoreleasepool.
Could anyone tell me what's going on? Is the weak object registered in autoreleasepool automatically?
Thanks!
I am reading the same book now and I found this part very confusing too. And I wrote a very similar program to test it and it didn't work. After some googling I've found that weak pointer is added to autorelease pool indeed:
But I still can't understand why object is released instantly, not when autorelease pool is drained. My guess some serious magic like compiler optimizations is involved.
That is absolute and total nonsense. __weak has nothing to do with autorelease pools whatsoever.
What the compiler does is add the location of the pointer to the list of "weak pointer" locations - note the location of the pointer, not the object. So when the object itself is released, all weak variables pointing to it can be set to nil.
And of course the compiler is clever and will optimise that kind of thing away when it can prove that it is not necessary.
What the author says about using weak variables safely is nonsense. The whole point of a weak variable is that it doesn't keep the object alive. So preventing the object from going away would be absolute nonsense. The whole idea is that it can go away, so sometimes you will check if the object is still there.
I don't have the book, so I cannot know if you are quoting the book correctly. If you are quoting it correctly, then the book is spouting dangerous nonsense and should be avoided. Well, to be honest, "Pro Multithreading" in a book title is off-putting already.
Absolutely, definitely not. That would be absolutely stupid.
It appears that ARC at the end of each scope decides whether or not to release + dealloc local variables.
from an article i found on the matter
so its seems at the end of the inner scope to your @autoreleasepool, arc is releasing the local variable