[英]NotificationCenter observers prevent dealloc with ARC
我正在嘗試調試一個最近轉換為使用ARC的項目。 我很難確定為什么對象沒有被釋放並留在內存中(是否有一種簡單的方法可以查看哪個引用將對象保存在內存中?)
通知中心鏈接似乎是一個問題。 在viewDidLoad上我注冊了三個通知:
[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];
}];
然后,當viewController完成時,我調用一個函數unLoad:
- (void) unLoad {
[[NSNotificationCenter defaultCenter] removeObserver:self];
_mediaPlayerHelper = nil;
_article = nil;
_tableView = nil;
}
我有一個單獨的函數的原因是除非釋放所有對象,否則不會調用viewDidUnload,所以我需要一些東西來釋放它們。 目前我在viewDidDisappear上調用它們。
但是,在注釋掉觀察者時,代碼工作正常(並且查看卸載),但是觀察者看起來不起作用並且視圖保留在內存中。 有什么建議么?
因為您正在使用帶有塊參數的通知方法,並且在塊中使用了對self
的強引用。 您應該使用觀察方法,該方法使用回調選擇器(因此不捕獲)或創建對self
的__weak
引用以在塊中使用。
打電話時您不會刪除觀察者
[[NSNotificationCenter defaultCenter] removeObserver:self];
您不必傳遞self
,而是傳遞addObserverForName:...
方法的值。
像這樣的東西。 對於所有觀察者。
@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;
// ...
}
使用弱引用自我不會刪除觀察者。 這將只允許取消分配您的視圖控制器。 但是觀察者塊仍然在通知中心。 並且每次都會調用它們。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.