在不延迟当前操作的情况下解雇NSNotification

时间:2013-09-30 19:09:06

标签: ios objective-c cocoa-touch

有没有办法解雇NSNotification(这可能触发相当多的工作)而不会延迟任何当前正在完成的代码?

具体来说,我有一个UIPanGestureRecognizer,允许用户平移几个月,一月,二月等。一旦用户抬起手指(识别器状态更改UIGestureRecognizerStateEnded),就会运行一些清理代码,包括一些UI(调整一个框架等),并且 - 重要的是 - 在选定的月份启动了NSNotification。

这在模拟器中运行顺畅,但是当我在iPhone 4上运行时,性能非常糟糕(即当我抬起手指时,UI会锁定+1.5秒)。如果我删除通知,则性能恢复良好。请注意,这些通知正在整个应用程序中发送(同步基于月份的日历,基于周的日历和事件列表),并且直到现在才显示性能问题。只有在他们与手势识别器一起使用时才会出现性能问题。

3 个答案:

答案 0 :(得分:1)

首先,您应该剖析以确切了解花费时间的内容。 1.5秒的延迟是一个很长的时间,无论是现在还是延迟到将来。

发布通知时,会立即广播和处理。您可以做的最好的事情是使用GCD或performSelector:withObject:afterDelay:delay为0)在runloop的下一次迭代中发布通知。

答案 1 :(得分:1)

使用NSNotificationQueue。这是最简单的方法。

答案 2 :(得分:0)

将dispatch_async()与performSelectorOnMainThread一起使用:withObject:waitUntilDone:是“解决NSNotification而不延迟当前操作”的一种解决方案。 NSNotificationQueue可能是另一种解决方案,但我没有发现它与dispatch_async一样有效。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
    [self performSelectorOnMainThread:@selector(performNotification:) withObject:someObject waitUntilDone:NO];
});

- (void)performNotification:(SomeClass*)someObject
{
    [[NSNotificationCenter defaultCenter] postNotificationName:MyNotificationName object:someObject];
}

(通过此SO article