Reputation: 4508
I am trying to debug a project which I have recently converted to use ARC. I am having a hard time determining why objects are not released and stay in memory (is there an easy way to see what reference keeps an object in memory?)
One problem seems with notification centre links. On viewDidLoad I register three notifications:
[notificationCenter addObserverForName: kAudioPlaybackStart
object: nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note) {
[self handle_PlaybackStateStart:nil];
}];
[notificationCenter addObserverForName: kAudioPlaybackStop
object: nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note) {
[self handle_PlaybackStateStop:nil];
}];
[notificationCenter addObserverForName: kAudioPlaybackPause
object: nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note) {
[self handle_PlaybackStatePause:nil];
}];
Then, when the viewController is done I call a function unLoad:
- (void) unLoad {
[[NSNotificationCenter defaultCenter] removeObserver:self];
_mediaPlayerHelper = nil;
_article = nil;
_tableView = nil;
}
The reason I have a separate function is that viewDidUnload is not called unless all objects are released, so I need something to release them. Currently I call them on viewDidDisappear.
However, the code works fine (and view unloads) when commenting out the observers, but with the observers it doesn't seem to work and the view stays in memory. Any suggestions?
Upvotes: 2
Views: 1399
Reputation: 101
You're not removing your observers when calling
[[NSNotificationCenter defaultCenter] removeObserver:self];
You have to pass not self
, but return values of addObserverForName:...
methods.
Something like this. For all of the observers.
@property (strong, nonatomic) id audioStartObserver;
-(void)viewDidLoad
{
[super viewDidLoad];
self.audioStartObserver = [notificationCenter addObserverForName: kAudioPlaybackStart
object: nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note) {
[self handle_PlaybackStateStart:nil];
}];
// ...
}
- (void) unLoad {
[[NSNotificationCenter defaultCenter] removeObserver:self.audioStartObserver];
self.audioStartObserver = nil;
// ...
}
Using weak reference to self will not remove the observer. This will just allow to dealloc your view controller. But observer blocks will still be in notification center. And they will be called each time.
Upvotes: 1
Reputation: 119041
Because you are using the notification methods which take a block argument and you use a strong reference to self
in the block. You should use the observation method which uses a callback selector (so there is no capture) or create a __weak
reference to self
to use in the blocks.
Upvotes: 6