Reputation: 1480
While reading a blog about concurrency in iOS, I stumbled upon the next code:
__weak id weakSelf = self;
[self.operationQueue addOperationWithBlock:^{
NSNumber* result = findLargestMersennePrime();
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
MyClass* strongSelf = weakSelf;
strongSelf.textLabel.text = [result stringValue];
}];
}];
The author explains that the use of weakref is needed since:
we need to make a weak reference to self, otherwise we create a retain cycle (the block retains self, the private operation queue retains the block, and self retains the operation queue). Within the block we convert it back to a strong reference to make sure it doesn’t get deallocated while running the block.
I can understand why the block would have retained self, but I don't understand why (and where exactly) the private operation queue retains the block and when/where self retaind the opeation queue. Any explanation would be much appreciated.
Upvotes: 2
Views: 646
Reputation: 24156
try to write this code without weak reference:
[self.operationQueue addOperationWithBlock:^{
NSNumber* result = findLargestMersennePrime();
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.textLabel.text = [result stringValue];
}];
}];
to make this code work - compiler retains reference to self
in operationQueue
to avoid situation when self
is deleted from memory and self.textLabel.text = ..
is executed, so it tries to guarantee that object will be alive.
This is where cycle is actually created:
to avoid this - you're creating week reference, so you're eliminating 2nd retention
PS. "block" is part of operationQueue, so we can assume just 2 items in this scheme.
Upvotes: 1