未删除iOS NSNotificationCenter观察者

未删除iOS NSNotificationCenter观察者,ios,objective-c,nsnotificationcenter,observers,Ios,Objective C,Nsnotificationcenter,Observers,我在AppDelegate中有以下代码。其目的是创建两个观察者,然后调用一些代码。一旦代码完成,它就会发布一个通知,然后观察者应该删除这两个观察者并调用完成处理程序 我的问题是,观察员似乎没有像我预期的那样被撤职。通知已发布,NSLog条目已写入控制台,因此我知道观察者正在工作。但是,在第二次调用时,NSLog会被调用两次,第三次调用三次,以此类推 我的想法是,这与从观察者运行的代码块中删除有关,但是,我不确定如何解决这个问题(如果确实是这个问题) 有人能解释一下我是如何做到这一点的吗 谢谢 -

我在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;
}
我的想法是,这是与移除在 但是,我不确定从观察者运行的代码块 我如何解决这个问题(如果问题确实是这样的话)

有人能解释一下我是如何做到这一点的吗

当然可以

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


只需使用获取这些方法的详细信息,或者一般来说,因为您的问题是关于可以使用哪些不需要block语句的其他方法,所以首先要查看API以检查类中的替代工具。

您没有将
self
注册为对象。此外,当通过
addObserverForName:
将块推送到堆栈上时,该方法尚未返回,因此
通知
nil

使用
创建全局对象,例如

__block __weak id notification;
那么


谢谢你的评论。非常感谢。翻译:当使用
addObserverForName
时,
self
不是观察者,因此调用
[中心移除观察者:self…]
无效。observer是从
addObserverForName
返回的对象,您必须使用它,但是这很棘手,因为在定义块并将其传递到方法时,它的值还不可用。使用
\u块
声明存储观察者结果的变量。
notification =  [[NSNotificationCenter defaultCenter] addObserverForName:@"fetchDidCompleteNewData" object:nil queue:nil usingBlock:^(NSNotification *completed) {

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