为什么不使用NSNotificationCenter调用块?

时间:2013-05-22 09:44:19

标签: objective-c

我刚刚遇到了NSNotificationCenter方法[NSNotificationCenter defaultCenter] addObserverForName: object: queue: usingBlock:方法,因为我开始习惯使用块,所以我决定尝试一下,因为我可以提高代码的可读性。

但由于某种原因,我无法让它发挥作用。出于什么原因,这不起作用

[[NSNotificationCenter defaultCenter] addObserverForName:@"SomeNotificationName"
                                                  object:self
                                                   queue:[NSOperationQueue mainQueue]
                                              usingBlock:^(NSNotification *note) {

                                                  NSLog(@"This doesn't work");
                                                  // ... want to do awesome stuff here...

                                              }];

这里的工作正常

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(aMethod)
                                             name:@"SomeNotificationName"
                                           object:nil];
//...
//....

- (void)aMethod {
    NSLog(@"This works");
    // ... doing awesome stuff here...
}

结束注释
谢谢,为了将来参考,这是我的最终解决方案

// declared instance variable id _myObserver;
//...

_myObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"SomeNotificationName"
                                                                          object:nil
                                                                           queue:[NSOperationQueue mainQueue]
                                                                      usingBlock:^(NSNotification *note) {

                                                                          NSLog(@"It's working! It's working!!");
                                                                          // ... again doing awesome stuff here...

                                                                      }];

最后,(当我完成对象时)

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

2 个答案:

答案 0 :(得分:5)

更仔细地阅读文档:)在块版本中,您必须存储返回的“令牌”对象,例如在ivar中。

id obj = [[NSNotificationCenter defaultCenter]
                  addObserverForName:@"SomeNotificationName"
                              object:self
                               queue:[NSOperationQueue mainQueue]
                          usingBlock:^(NSNotification *note) {
                              NSLog(@"This doesn't work");
                              // ... want to do awesome stuff here...
                          }];
//you need to retain obj somehow (e.g. using ivar)
//otherwise it will get released on its own under ARC

另外(如文档中所述),不要忘记在完成后删除观察者。在我的情况下,这通常发生在我的窗口/视图控制器的dealloc方法中。在您的情况下,它可能在不同的地方。 (当然,如果你希望观察者退出你的应用程序,你就不需要这样做了。)

- (void)dealloc {      
  //assuming you stored it in _obj ivar
  [[NSNotificationCenter defaultCenter] removeObserver:_obj];

  //no super dealloc under ARC
}

答案 1 :(得分:1)

两种方法中的object参数都是通知的发件人。

在基于块的一个中,您正在传递self的基于选择器的nil。这意味着基于块的观察者将只收听self生成的通知。