有一个简单的方法(在Cocoa / iOS中)排队方法调用在下一个运行循环中运行一次吗?

UIView有一个setNeedsDisplay方法,可以在同一个事件循环内多次调用,安全的知道,重绘工作很快就会发生,只有一次。

有这种行为cocoa的通用机制吗? 一种说法:“根据需要多次排队select器,当时间到了,select器将运行一次并清除队列。

我知道我可以在我的目标或者NSOperationQueue中进行某种状态跟踪。 我只是想知道是否有一个我错过了轻量级的方法。

(当然,答案可能是“不”)。

setNeedsDisplay不是你所描述的一个很好的例子,因为每次你调用它时,它都会运行。 它只是设置一个标志。 但问题是好的。

一个解决scheme是使用NSNotificationCoalescingOnName使用NSNotificationCoalescingOnName

另一个解决scheme是build立一个蹦床来做自我凝聚。 我没有一个非常好的蹦床博客参考,但这里是一个例子( LSTrampoline )。 如果你想在一段时间内合并信息,build立这个并不难。 我曾经build立了一个forwardInvocation:的蹦床forwardInvocation:类似这样:

 - (void)forwardInvocation:(NSInvocation *)invocation { [invocation setTarget:self.target]; [invocation retainArguments]; [self.timer invalidate]; self.timer = [NSTimer scheduledTimerWithTimeInterval:self.timeout invocation:invocation repeats:NO]; } 

这实际上是将所有消息在时间段内合并到对象(不仅仅是匹配消息)。 这就是我所需要的特殊问题。 但是你可以扩展这个来跟踪哪个select器被合并,并检查你的调用,看看它们是否“足够”匹配。

为了让它在下一个事件循环中运行,只需将timeout设置为0即可。

我保留有关蹦床的博客的意思。 必填先令:我即将出版的书籍将在第4章和第20章中介绍蹦床。

 [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(doTheThing:) object:someObject]; [self performSelector:@selector(doTheThing:) withObject:someObject afterDelay:0]; 

这并不是UIView完全是这样做的,因为setNeedsDisplay只是设置一个标志,内部的UIView机制确保在设置绘图环境之后调用drawRect:但是这是一种通用的方法,并且不需要任何特殊的状态跟踪类。