BlackMouse
BlackMouse

Reputation: 4572

ARC: Dealloc not being called

I don't understand why I need to have a weak self in some blocks, while others seems to work fine.

If I don't have a weak ref to self with the Notification block, the dealloc won't be released. It works perfectly fine with the second though.

//When using this, dealloc is NOT being called
[[NSNotificationCenter defaultCenter] addObserverForName:PROD_DONE object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
    [self hideAds];
}];

//When using this, dealloc IS being called
[_match endMatchInTurnWithMatchData:_match.matchData completionHandler:^(NSError *error) {
    [self hideAds];
}];

If I create a weak ref to self, it works:

__weak GameViewController *weakSelf = self;
[[NSNotificationCenter defaultCenter] addObserverForName:PROD_DONE object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
    [weakSelf hideAds];
}];

Upvotes: 2

Views: 2001

Answers (1)

dtuckernet
dtuckernet

Reputation: 7895

This is because one reference goes away over time (for example - when the completion handler is called), the block is released. In this case, there is no retain cycle, because the reference to self will be released.

However, with the NSNotification example, the block reference must always be retained (unless it is removed manually) because it is still listening for the NSNotification. In this case, the reference to self causes a retain cycle causing the class to not be retained.

Upvotes: 3

Related Questions