NSObject接收NSNotification时的调用方法问题求助
排查NSNotification收不到的常见问题
兄弟,我来帮你捋捋可能导致你收不到通知的几个常见坑,你逐个排查下:
1. 观察者注册时机不对或对象不匹配
- 首先得确认注册观察者的代码是在通知发送之前执行的。比如如果你的自定义NSObject一初始化就启动异步任务,但你的观察者(比如ViewController)是之后才注册的,那通知发出去的时候还没观察者,自然收不到。
- 检查
addObserver:selector:name:object:里的object参数:如果发送通知时用的是postNotificationName:object:self,那注册时object传nil是能收到的,但如果注册时指定了其他对象,就会过滤掉这个通知;反过来,如果发送时object是nil,注册时却指定了特定对象,也收不到。要保证两者匹配。
2. Selector方法签名或拼写错误
- 通知对应的selector方法,最稳妥的签名是带
NSNotification参数的:- (void)handleDownloadFinished:(NSNotification *)notification; - 重点检查selector的拼写是否和方法名完全一致,包括大小写!比如你是不是把
@selector(downloadFinished)写成了@selector(downloadFinish),或者方法名是onDownloadFinished但selector写错了,这种低级错误很容易犯。
3. 观察者对象被提前释放了
- 如果注册观察者的对象(比如你的UITableView所在的ViewController)在通知发送之前就被销毁了,那肯定收不到通知。你可以在这个对象的
dealloc方法里加个打印,看看是不是提前释放了。另外记得在dealloc里手动移除观察者([[NSNotificationCenter defaultCenter] removeObserver:self]),虽然iOS9之后系统会自动处理,但手动移除更稳妥。
4. 通知名称不匹配
- 仔细核对发送通知和注册观察者时的通知名称,有没有拼写错误、大小写不一致或者多了空格?比如发送用
@"DownloadComplete",注册用@"DownloadCompleted",差一个字母就完全收不到。
5. 异步线程的小细节
- 虽然NSNotificationCenter会在发送通知的线程执行selector,但如果你的自定义NSObject在后台线程发通知,而你的观察者方法里有UI操作,需要切回主线程,但你说连打印都没输出,这个大概率不是主要问题,但也可以确认下异步任务的回调是不是正常执行了(你说发送通知的代码里其他打印正常,那这点可能没问题)。
给你个参考代码示例:
注册观察者(比如ViewController的viewDidLoad里)
- (void)viewDidLoad { [super viewDidLoad]; // 注册通知观察者 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(downloadFinished:) name:@"MyDownloadFinishedNotification" object:nil]; // 初始化自定义NSObject,启动异步任务 MyCustomModel *model = [[MyCustomModel alloc] init]; } - (void)downloadFinished:(NSNotification *)notification { NSLog(@"Download Finished"); // 更新数据源并刷新表格 [self.dataSource addObject:notification.object]; dispatch_async(dispatch_get_main_queue(), ^{ [self.tableView reloadData]; }); } - (void)dealloc { // 移除观察者 [[NSNotificationCenter defaultCenter] removeObserver:self]; }
发送通知(自定义NSObject的异步完成回调里)
- (void)asyncInitTask { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 模拟异步初始化任务 [NSThread sleepForTimeInterval:2]; NSLog(@"Async init done"); // 发送通知 [[NSNotificationCenter defaultCenter] postNotificationName:@"MyDownloadFinishedNotification" object:self]; }); }
内容的提问来源于stack exchange,提问作者Nicholas Zana
相关产品推荐
相关产品推荐

