1

我编写了以下代码来使用 NSNotificationQueue 执行合并。即使事件发生多次,我也只想发布一个通知。

- (void) test000AsyncTesting
{
    [NSRunLoop currentRunLoop];
    [[NSNotificationCenter defaultCenter] addObserver:self             selector:@selector(async000:) name:@"async000" object:self];
    [[NSNotificationQueue defaultQueue] enqueueNotification:[NSNotification notificationWithName:@"async000" object:self]
    postingStyle:NSPostWhenIdle coalesceMask:NSNotificationCoalescingOnName forModes:nil];

    while (i<2)
    {
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
        NSLog(@"Polling...");
        i++;
    }
}

- (void) async000:(NSNotification*)notification;
{
    NSLog(@"NSNotificationQueue");
}

每次调用“test000AsyncTesting”方法时,同名的通知都会被添加到队列中。根据合并的概念,如果队列有任意数量的通知但名称相同,则它只会发布一次。但是当我运行我的代码时,'async000:' 被多次调用,这与添加到 NSNotificationQueue 的通知数量完全相同。我认为合并不起作用。
对我来说,在这两种情况下,代码的执行都是一样的:

案例1:[[NSNotificationQueue defaultQueue] enqueueNotification:[NSNotification notificationWithName:@"async000" object:self] 张贴风格:NSPostWhenIdle coalesceMask:NSNotificationCoalescingOnName forModes:nil];

案例2:[[NSNotificationQueue defaultQueue] enqueueNotification: [NSNotification notificationWithName:@"async000" object:self] postingStyle:NSPostWhenIdle];

请告诉我代码中的错误。

4

2 回答 2

7

合并只合并在控制流返回到运行循环之前发生的通知。如果您在通过运行循环的后续行程中将通知排入队列,这将导致单独的通知调用。

要看到这一点,请将 test000AsyncTesting 更改为将 2 个通知排入队列,如下所示:

[[NSNotificationQueue defaultQueue] enqueueNotification:[NSNotification notificationWithName:@"async000" object:self]
postingStyle:NSPostWhenIdle coalesceMask:NSNotificationCoalescingOnName forModes:nil];

[[NSNotificationQueue defaultQueue] enqueueNotification:[NSNotification notificationWithName:@"async000" object:self]
postingStyle:NSPostWhenIdle coalesceMask:NSNotificationCoalescingOnName forModes:nil];

然后async000在轮询时只会被调用一次。

为了进行测试,将 coalesceMask 更改为 NSNotificationNoCoalescing 然后您将在轮询时看到 2 次对 async000 的调用。

于 2011-01-20T18:57:11.280 回答
0

您必须“注销”通知;尝试这个:

-(void)dealloc
{    
    [[NSNotificationCenter defaultCenter]removeObserver:self name:@"async000" object:nil];

    [super dealloc];
}
于 2012-07-04T17:12:22.997 回答