使用NSNotificationQueue时合并

时间:2011-01-12 11:45:10

标签: iphone objective-c coalescing

我编写了以下代码以使用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]     postingStyle:NSPostWhenIdle coalesceMask:NSNotificationCoalescingOnName forModes:nil];

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

请告诉我的代码中的错误。

2 个答案:

答案 0 :(得分:6)

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

要查看此内容,请将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。

答案 1 :(得分:0)

您必须“取消注册”通知;试试这个:

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

    [super dealloc];
}