簡體   English   中英

NotificationCenter觀察者防止使用ARC取消分配

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM