NSNotificationCenter 的帖子导致“EXC_BAD_ACCESS”异常

问题描述 投票:0回答:6

A

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

[[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 发布通知时,同样的概念也适用,但这应该不重要,对吧?

ios objective-c iphone exc-bad-access nsnotificationcenter
6个回答
131
投票

您的一个订阅者已被取消分配。确保在你的 dealloc 中调用

[[NSNotificationCenter defaultCenter] removeObserver:self]
(如果不是更早的话)。


11
投票
即使在验证了 dealloc 存在之后,

EXC_BAD_ACCESS
也可能发生,如下所示:

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

上面的方法大多数情况下可以解决问题,但显然我的原因是我间接添加了观察者并将

selector:
设置为
nil
,如下所示:

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

...所以当我发布带有

notificationName
的内容时,
EXC_BAD_ACCESS
发生了。

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


1
投票

我在 Swift 中遇到了同样的问题。问题是函数目标有一个

closure
参数,默认值:

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

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

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

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


0
投票

对于任何收到此错误并使用 async/await 的人,请务必检查其他问题是否可能不是原因 https://stackoverflow.com/a/76066999/2828729

tl;dr:在撰写本文时,

@objc
选择器和
async
方法不能很好地结合在一起


0
投票

随着 async/await 的引入,还要注意选择器不要有

async
关键字。


0
投票

错误的方法头也可能会发生此错误。我刚刚收到错误,因为在通知发送对象时不接受对象。

NotificationCenter.default.post(name: MyNotification.name, object: self)

将与:

合作
@objc func myFunction(_ sender: AnyObject) async throws {}

但不是与

@objc func myFunction() async throws {}
© www.soinside.com 2019 - 2024. All rights reserved.