In this question, I asked about the following code and retain cycles:
__weak Cell *weakSelf = self;
NSBlockOperation *op = [NSBlockOperation blockOperationWi
Your old code creates this retain cycle if you don't use __weak
:
(NSBlockOperation *)op
retains the outer blockself
(if you're not using __weak
)self
retains (NSOperationQueue *)renderQueue
(NSOperationQueue *)renderQueue
retains (NSBlockOperation *)op
None of the objects in that cycle can be deallocated unless one of those links is broken. But the code you showed us does break the retain cycle. When op
finishes executing, renderQueue
releases it, breaking the retain cycle.
I suspect that your new code creates this retain cycle:
(MBItem *)close
retains the blockself
self
retains childObject
childObject
retains (NSMutableArray *)items
(NSMutableArray *)items
retains (MBItem *)close
If nothing happens to break one of those links, none of the objects in the cycle can be deallocated. You haven't shown us any code that breaks the retain cycle. If there is no event that explicitly breaks it (for example by clearing out childObject.items
), then you need to use __weak
to break the retain cycle.
I can't tell you the reason for the retain-cycle in your second example, because I don't know MBItem
, but there are two different usage patterns with blocks.
If you expect your block to execute in any case, then you can just use self
in the block:
[startSomeOperationWithCompletionBlock:^{
[self doSomeThing];
}];
The block retains a reference to self
, so that self
is not deallocated before the block is executed. But after the block has executed, this reference (and the retain cycle) is gone.
If you possibly want that self
is deallocated before the block has executed,
or if it is possible that the block will not be called at all,
then you have to use a weak reference and check the value inside the block:
__weak MyClass *weakSelf = self;
[startSomeOperationWithCompletionBlock:^{
MyClass *strongSelf = weakSelf;
if (strongSelf) {
[strongSelf doSomeThing];
}
}];
The block does not retain self
in this case, so that self
can be deallocated. In that case, weakSelf
is set to nil
automatically. Therefore, if the block is executed finally, you have to check first if weakSelf
is still valid. (Or you can just use it, because sending messages to nil
is a no-op.)
Assigning a strong reference strongSelf
inside the block prevents self
from being deallocated while the block is executing.