我在视图控制器中有一个设置一些通知的方法:
- (void)processState
{
MYGame *game = [[MYGameManager sharedInstance] getGameAtIndex:self.indexPath.row];
if(game)
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notification_gameUpdated:) name:kMYNotificationGameUpdated object:game];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notification_gameEnded:) name:kMYNotificationGameEnded object:game];
}
}
然后有一个游戏更新方法,每隔一段时间调用一次:
- (void)notification_gameUpdated:(NSNotification *)notification
{
MYGame *game = notification.object;
_game_status = (game.entity.bet.isWinning) ? MYGameStatusWin : MYGameStatusLose;
}
最后,当比赛结束时:
- (void)notification_gameEnded:(NSNotification *)notification
{
MYGame *game = notification.object;
// Clear the notifications
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMYNotificationGameUpdated object:game];
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMYNotificationGameEnded object:game];
self.gameIsActive = NO;
}
麻烦的是,即使我删除观察者(并且断点显示正在发生这种情况),那么notification_gameUpdated:
方法仍然被调用。如果我将其更改为
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMYNotificationGameUpdated object:nil];
这仍然不清楚。但如果我把它改成
[[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:game];
然后 清除它。
[[NSNotificationCenter defaultCenter] removeObserver:self];
但是我并不热衷于这样做,因为我觉得代码很干净而且我不想要任何"陷阱"如果我需要添加更多的观察者,那就更进一步了。我已经检查了其余的代码,并且找不到任何其他类将观察者添加到此对象,尽管其他视图控制器会侦听相同的消息。
答案 0 :(得分:3)
processState
被调用多次?这可以解释你所看到的行为。
如果是,解决问题的一种方法是在添加侦听器之前始终删除侦听器。参见例如this answer
答案 1 :(得分:1)
编辑#2
尝试注册object:nil
,当您发布通知时,请在game
字典中包含对userInfo
的引用。然后,在接收器中,您可以与game
进行比较,并执行您想要的任何操作(如果匹配)。这应该会让您获得与使用object:game
时相同的行为,尽管它无法解释您当前实施的原因是什么
当您注册这样的通知时:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(notification_gameUpdated:)
name:kMYNotificationGameUpdated
object:game];
@selector
仅在game
的特定实例是发件人时才会执行。
您是否有可能在注册后重新初始化game
的共享实例?这可能会导致您遇到的行为
尝试使用object:nil
注册通知,看看会发生什么。 (假设没有多个游戏并发运行)
答案 2 :(得分:0)
事实证明,问题的原因是Method Swizzling。我正在处理的项目已addObserver:selector:name:object:
和removeObserver:name:object:
进行了调整。问题是虽然addObserver
已正确处理,但removeObserver
仅在特定条件下删除对象。这显然需要改变......
但是我发布这个作为对他人的警告......嗖嗖声对你的健康有害!
任何时候的道歉都浪费了。