In this question, I asked about the following code and retain cycles:
__weak Cell *weakSelf = self;
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
UIImage *image = /* render some image */
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[weakSelf setImageViewImage:image];
}];
}];
[self.renderQueue addOperation:op];
All answers state that using a weak reference here was not necessary, since this code does not result in a retain cycle. However, while experimenting with some more code, the following does result in a retain cycle (if I don’t use a weak reference, the current view controller is not deallocated)
//__weak ViewController *weakSelf = self;
MBItem *close = [[MBItem alloc] initWithBlock:^{
[self dismissModalWithDefaultAnimation:NO];
}];
NSMutableArray *items = [[NSMutableArray alloc] initWithObjects:close, nil];
[self.childObject setItems:items];
Why would the second one result in a retain cycle but not the first one?
Your old code creates this retain cycle if you don’t use
__weak:(NSBlockOperation *)opretains the outer blockself(if you’re not using__weak)selfretains(NSOperationQueue *)renderQueue(NSOperationQueue *)renderQueueretains(NSBlockOperation *)opNone 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
opfinishes executing,renderQueuereleases it, breaking the retain cycle.I suspect that your new code creates this retain cycle:
(MBItem *)closeretains the blockselfselfretainschildObjectchildObjectretains(NSMutableArray *)items(NSMutableArray *)itemsretains(MBItem *)closeIf 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__weakto break the retain cycle.