潜在问题
- 线程安全问题:
- 具体场景:不同线程同时向通知中心注册或发送通知。例如,线程A和线程B几乎同时调用
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(someSelector:) name:@"SomeNotification" object:nil]
进行注册,可能导致注册状态混乱,通知可能无法正确发送到观察者。
- 解决方案:使用线程同步机制,如GCD队列。可以创建一个串行队列,将所有与通知中心注册和发送相关的操作都放在这个队列中执行。
- 关键代码:
dispatch_queue_t serialQueue = dispatch_queue_create("com.example.notificationQueue", DISPATCH_QUEUE_SERIAL);
dispatch_async(serialQueue, ^{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(someSelector:) name:@"SomeNotification" object:nil];
});
- 死锁问题:
- 具体场景:假设线程A发送一个通知,观察者在处理通知时又发送另一个通知,而这个新通知的观察者又在同一个线程等待第一个通知处理完成。例如,线程A发送
NotificationA
,观察者在处理 NotificationA
时发送 NotificationB
,而处理 NotificationB
的代码又依赖线程A处理完 NotificationA
,就可能产生死锁。
- 解决方案:避免在通知处理代码中发送可能导致死锁的通知。如果必须发送,可以使用异步方式发送通知。
- 关键代码:
- (void)handleNotificationA:(NSNotification *)notification {
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:@"NotificationB" object:nil];
});
}
- 通知接收顺序问题:
- 具体场景:在多线程环境下,由于不同线程发送通知的时机不同,可能导致观察者接收到通知的顺序与预期不符。例如,原本希望先处理通知A,再处理通知B,但由于线程执行的不确定性,可能先收到通知B。
- 解决方案:可以在通知处理代码中增加逻辑判断,确保按预期顺序处理。或者在发送通知时带上一些标识信息,在观察者端根据这些标识信息进行处理。
- 关键代码:
// 发送通知时带上标识
NSDictionary *userInfo = @{@"sequence": @1};
[[NSNotificationCenter defaultCenter] postNotificationName:@"NotificationA" object:nil userInfo:userInfo];
// 观察者处理
- (void)handleNotification:(NSNotification *)notification {
NSNumber *sequence = notification.userInfo[@"sequence"];
if ([sequence integerValue] == 1) {
// 按顺序处理
}
}