Kri*_*ins 13 cocoa cocoa-touch objective-c ios
UIView有一个setNeedsDisplay方法,可以在同一个事件循环中多次调用,安全知道重绘工作很快就会发生,而且只有一次.
Cocoa有这种行为的通用机制吗?一种说法,"按照你喜欢的方式多次排队一个选择器,当它的时候,选择器将运行一次并清除队列."
我知道我可以通过目标中的某种状态跟踪或使用NSOperationQueue来执行此操作.我只是想知道是否有一种我错过的轻量级方法.
(当然,答案可能是"不".)
Rob*_*ier 12
setNeedsDisplay并不是你所描述的一个很好的例子,因为它实际上每次调用时都会运行.它只是设置了一面旗帜.但问题是好的.
一个解决方案是使用NSNotificationQueue用NSNotificationCoalescingOnName.
另一个解决方案是建立一个蹦床来自己进行合并.我没有关于蹦床的真正好的博客参考,但这里有一个例子(LSTrampoline).如果你想在一段时间内合并消息,那么构建它并不困难.我曾经建造过一个forwardInvocation:类似于此的蹦床:
- (void)forwardInvocation:(NSInvocation *)invocation {
[invocation setTarget:self.target];
[invocation retainArguments];
[self.timer invalidate];
self.timer = [NSTimer scheduledTimerWithTimeInterval:self.timeout invocation:invocation repeats:NO];
}
Run Code Online (Sandbox Code Playgroud)
这实际上会在一段时间内将所有消息合并到对象(而不仅仅是匹配消息).这就是我对特定问题所需要的一切.但您可以对此进行扩展以跟踪正在合并的选择器,并检查您的调用以查看它们是否"足够"匹配.
要使其在下一个事件循环上运行,只需将timeout设置为0.
关于蹦床的博客,我一直有意思.要求先令:我即将出版的书涵盖了第4章和第20章中的蹦床.
[NSObject cancelPreviousPerformRequestsWithTarget:self
selector:@selector(doTheThing:)
object:someObject];
[self performSelector:@selector(doTheThing:)
withObject:someObject
afterDelay:0];
Run Code Online (Sandbox Code Playgroud)
这并不是UIView这样做的原因,因为setNeedsDisplay只需设置一个标志,内部UIView机制确保drawRect:在设置绘图环境后调用,但这是一种通用的方式,并且不需要在类中进行任何特殊的状态跟踪.
| 归档时间: |
|
| 查看次数: |
1688 次 |
| 最近记录: |