有一个简单的方法(在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:
但是这是一种通用的方法,并且不需要任何特殊的状态跟踪类。