2015-11-09 91 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];