NSNotificationCenter的帖子导致“ EXC_BAD_ACCESS”异常


67

AUIViewController将自身添加到默认中心:

[[NSNotificationCenter defaultCenter]
 addObserver:self
 selector:@selector(editFood)
 name:@"editFood"
 object:nil];

然后,UITableView委托NSObject发布NSNotification

[[NSNotificationCenter defaultCenter]
 postNotificationName:@"editFood"
 object:self];

在运行时,它将获得EXC_BAD_ACCESS异常。

defaultCenter得到释放的地方?当我从UIViewController向UIViewController发布通知时,相同的概念起作用,但这没关系,对吧?


它到底在哪里崩溃?
直到

3
添加[[NSNotificationCenter defaultCenter] removeObserver:self]-(void)dealloc{}场景中的方法可能会解决这个问题你。它为我工作;我遇到了同样的问题。祝好运!
nodebase 2014年

Answers:


131

您的一个订阅者已被释放。确保调用[[NSNotificationCenter defaultCenter] removeObserver:self]您的dealloc(如果不早的话)。


3
谢谢,我才意识到自己的错误(研究并研究了四个小时之后)。释放呼叫后,我尝试引用的对象。调试器使它看起来像是抛出EXC_BAD_ACCESS异常的地方。
保罗·乔丹

4
@Paul:僵尸仪器确实有助于调试此类问题。
Sven

@Sven谢谢,谢谢。我实际上曾经尝试使用过一次,却不知道怎么做。我在项目plist中添加了一个环境变量,但这是行不通的。
保罗·乔丹

我在收到名为EXC_BAD_ACCESS的通知后释放该对象,我该如何解决呢?
2013年

3
EXC_BAD_ACCESS也不例外,它是无效的内存访问
junglecat

11

EXC_BAD_ACCESS 即使在验证dealloc存在之后也可能发生,如下所示:

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

上面的内容通常会解决大多数问题,但是显然,我的原因是我间接地向观察者添加了一个selector:集合,nil如下所示:

[NSNotificationCenter.defaultCenter addObserver:self
                                         selector:nil
                                             name:notificationName
                                           object:nil];

...所以当我发布有关该内容的信息时notificationNameEXC_BAD_ACCESS发生了。

解决方案是发送一个实际上指向某个对象的选择器。


1
是的,我自己找到了这个,我把NULL选择器当作临时选择器,就像哦,让我去创建该方法,然后我忘了稍后再更新选择器参数(DOH),是的,EXC_BAD_ACCESS结果。
比利·格雷

0

我在Swift中也遇到了同样的问题。问题在于函数目标closure具有默认值的参数:

@objc func performFoo(completion: (() -> Void)? = nil) {
   ...
}

在用closure参数替换Notification参数后,它起作用了:

@objc func performFoo(notification: Notification) {
    ...
}

我必须进行一些重构以使其以正确的方式工作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.