我不太明白 CALayer 是怎么做的display
and drawInContext
与......有关drawRect
视图中。
如果我有一个 NSTimer 来设置[self.view setNeedsDisplay]
每 1 秒,然后drawRect
每 1 秒调用一次,如里面的 NSLog 语句所示drawRect
.
但是如果我子类化 CALayer 并将其用于视图,如果我制作display
方法为空,然后现在drawRect
从未被调用过。Update: But display
每 1 秒调用一次,如 NSLog 语句所示。
如果我删除那个空的display
方法并添加一个空drawInContext
方法,再次,drawRect
从未被调用过。Update: But drawInContext
每 1 秒调用一次,如 NSLog 语句所示。
究竟发生了什么?看起来display
可以有选择地调用drawInContext
and drawInContext
可以有选择地以某种方式调用drawRect
(如何?),但是这里的真实情况是什么?
更新:答案有更多线索:
我改变了CoolLayer.m
代码如下:
-(void) display {
NSLog(@"In CoolLayer's display method");
[super display];
}
-(void) drawInContext:(CGContextRef)ctx {
NSLog(@"In CoolLayer's drawInContext method");
[super drawInContext:ctx];
}
所以,假设,如果视图中的位置 (100,100) 处有一个月亮(由 Core Graphics 绘制的圆),现在我将其更改为位置 (200,200),自然地,我会调用[self.view setNeedsDisplay]
,现在,CALayer 将根本没有新视图图像的缓存,因为我的drawRect
规定月亮现在应该如何显示。
即便如此,入口点还是 CALayer 的display
,然后是 CALayer 的drawInContext
:如果我设置一个断点drawRect
,调用堆栈显示:
所以我们可以看到 CoolLayer 的display
首先输入,然后进入 CALayer 的display
,然后是 CoolLayer 的drawInContext
,然后是 CALayer 的drawInContext
,即使在这种情况下,新图像不存在这样的缓存。
最后,CALayer 的drawInContext
致电代表的drawLayer:InContext
。委托是视图(FooView 或 UIView)...并且drawLayer:InContext
是 UIView 中的默认实现(因为我没有覆盖它)。终于是这样了drawLayer:InContext
calls drawRect
.
所以我猜测两点:为什么即使没有图像缓存它也会进入CALayer?因为通过这个机制,图像是在上下文中绘制的,最后返回到display
,并且 CGImage 是从该上下文创建的,然后它现在被设置为缓存的新图像。这就是 CALayer 缓存图像的方式。
我不太确定的另一件事是:如果[self.view setNeedsDisplay]
总是触发drawRect
那么什么时候可以使用CALayer中的缓存图片呢?难道是……在Mac OS X上,当另一个窗口覆盖了一个窗口时,现在顶部的窗口被移走了。现在我们不需要打电话drawRect
重绘所有内容,但可以使用 CALayer 中的缓存图像。或者在 iOS 上,如果我们停止应用程序,执行其他操作,然后返回应用程序,则可以使用缓存的图像,而不是调用drawRect
。但如何区分这两类“脏”呢?一是“未知的肮脏”——月亮需要按照规定重新绘制drawRect
逻辑(它可以使用随机数作为坐标)。另一种类型的脏是它被掩盖或消失,现在需要重新显示。