2015-11-09 117 views
1

我用2 NSNotificationCenter,爲了避免保留週期我已經創建了一個weakSelf這樣的:__unsafe_unretained AugmentedRealityViewController *weakSelf = self;無法刪除NSNotificationCenter

[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { 


     if (weakSelf.architectWorldNavigation.wasInterrupted) { 
      [weakSelf.architectView reloadArchitectWorld]; 
     } 

     [weakSelf startWikitudeSDKRendering]; 
    }]; 
    [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillResignActiveNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { 

     [weakSelf stopWikitudeSDKRendering]; 
    }]; 

的問題是,即使我刪除它們dealloc內他們一直被解僱和應用程序崩潰。

dealloc內部,以便去除NSNotificationCenter我使用下面的代碼:

- (void)dealloc 
{ 
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 

    [self.architectView removeFromSuperview]; 
} 

,當我離開的ViewController但通知仍然有效,它被稱爲..誰能告訴我什麼是錯的代碼以及如何解決這個問題?

+0

你在哪裏添加觀察者?在應用程序代表? –

+0

@ Mr.T在我的ViewDidLoad – Signo

+0

離開視圖控制器,你的意思是什麼?這是否意味着回家或轉移到另一個VC? –

回答

3

通常,您最好選擇處理通知的選擇器方法。使用基於塊的API肯定有很好的理由,但你的情況似乎是爲其他方式量身定做的。

[[NSNotificationCenter defaultCenter] 
    addObserver:self 
     selector:@selector(applicationDidBecomeActiveNotification:) 
      name:UIApplicationDidBecomeActiveNotification 
     object:nil]; 

[[NSNotificationCenter defaultCenter] 
    addObserver:self 
     selector:@selector(applicationWillResignActiveNotification:) 
      name:UIApplicationWillResignActiveNotification 
     object:nil]; 

- (void)applicationDidBecomeActiveNotification:(NSNotification*)notification { 
    if (self.architectWorldNavigation.wasInterrupted) { 
     [self.architectView reloadArchitectWorld]; 
    } 
    [self startWikitudeSDKRendering]; 
} 

- (void)applicationWillResignActiveNotification:(NSNotification*)notification { 
    [self stopWikitudeSDKRendering]; 
} 

然後,您可以簡單地刪除自己,因爲您是實際的觀察者。

- (void)dealloc { 
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 
} 
1

1)刪除__unsafe_unretained屬性。它可能沒有傷害,但它沒有做任何有用的事情。

2)您沒有從[NSNotificationCenter addObserverForName:object:queue:usingBlock:]捕獲返回值,這意味着您無法取消註冊通知。此方法創建一個代理對象,用於偵聽通知並運行該塊。如果您在某個時刻不保留引用並取消註冊,則會出現內存泄漏和不需要的通知處理程序。

1

那是因爲你沒有添加selfNSNotificationCenter,要添加的block,然後試圖消除self

當您添加模塊來NSNotificationCenter它實際上返回一個以後可以用它來刪除該對象代碼通知中心

__unsafe_unretained AugmentedRealityViewController *weakSelf = self; 

self.becomeActiveHandler = [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { 
    if (weakSelf.architectWorldNavigation.wasInterrupted) { 
     [weakSelf.architectView reloadArchitectWorld]; 
    } 
    [weakSelf startWikitudeSDKRendering]; 
}]; 

self.willResignActiveHandler = [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillResignActiveNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { 
    [weakSelf stopWikitudeSDKRendering]; 
}]; 

,然後在dealloc中,你可以刪除這些處理器

[[NSNotificationCenter defaultCenter] removeObserver:self.becomeActiveHandler]; 
[[NSNotificationCenter defaultCenter] removeObserver:self.willResignActiveHandler];