iOS NSNotificationCenter Observer未被删除

时间:2014-05-04 11:58:07

标签: ios objective-c nsnotificationcenter observers

我在AppDelegate中有以下代码。目的是创建几个观察者,然后调用一些代码。一旦该代码完成,然后发布通知,然后观察者应该删除两个观察者并调用完成处理程序。

我的问题是看来观察员没有像我预期的那样被删除。发布通知,并将NSLog条目写入控制台,因此我知道观察者正在工作。但是,在第二次调用时,NSLog被调用两次,第三次调用三次等。

我的想法是,这与在观察者运行的代码块内的删除有关,但是,我不确定如何解决这个问题(如果这确实是问题所在)。

有人可以如此友善地解释我是如何实现这一目标的吗?

感谢。

-(void) application:(UIApplication *)application performFetchWithCompletionHandler:
(void (^)(UIBackgroundFetchResult))completionHandler {

    [[NSNotificationCenter defaultCenter] addObserverForName:@"fetchDidCompleteNewData" object:nil
                                                     queue:nil usingBlock:^(NSNotification *completed) {

                                                         //Remove Observers
                                                         [[NSNotificationCenter defaultCenter] removeObserver:self
                                                                                                         name:@"fetchDidCompleteNewData"
                                                                                                       object:nil];
                                                         [[NSNotificationCenter defaultCenter] removeObserver:self
                                                                                                         name:@"fetchDidCompleteNoData"
                                                                                                       object:nil];


                                                         // Post completion
                                                         completionHandler(UIBackgroundFetchResultNewData);
                                                         NSLog(@"Background fetch completed... New Data");
                                                     }];

    [[NSNotificationCenter defaultCenter] addObserverForName:@"fetchDidCompleteNoData" object:nil
                                                       queue:nil usingBlock:^(NSNotification *completed) {

                                                           //Remove Observers
                                                           [[NSNotificationCenter defaultCenter] removeObserver:self
                                                                                                           name:@"fetchDidCompleteNoData"
                                                                                                         object:nil];

                                                           [[NSNotificationCenter defaultCenter] removeObserver:self
                                                                                                           name:@"fetchDidCompleteNewData"
                                                                                                         object:nil];

                                                           //post completion
                                                           completionHandler(UIBackgroundFetchResultNoData);
                                                           NSLog(@"Background fetch completed... No New Data");

                                                       }];

    GetDetails *getDetails = [[GetDetails alloc] init];
    [getDetails backgroundRefresh];

}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];

    return YES;
}

2 个答案:

答案 0 :(得分:5)

您没有将self注册为对象。此外,当块被addObserverForName:推入堆栈时,该方法尚未返回,因此notificationnil

使用block创建一个全局对象,例如

__block __weak id notification;

然后,

notification =  [[NSNotificationCenter defaultCenter] addObserverForName:@"fetchDidCompleteNewData" object:nil queue:nil usingBlock:^(NSNotification *completed) {

   //Remove Observers
   [[NSNotificationCenter defaultCenter] removeObserver:notification];
}];

答案 1 :(得分:2)

  

我的想法是,这与移除内部有关   但是,我不确定从观察者运行的代码块   我如何解决这个问题(如果这确实是问题所在)。

     

有人可以如此友善地解释我是如何实现这一目标的吗?

当然可以。

您可以通过不使用addObserverForName:object:queue:usingBlock:方法并使用addObserver:selector:name:object:方法轻松测试您的理论,其中selector是您调用的函数的名称,而不是使用块

只需使用API guide for NSNotificationCenter获取有关这些方法的详细信息,或者一般情况下,因为您提出的问题是您可以使用哪种不需要块语句的方法,请咨询API是第一个检查的方法课堂上的替代工具。