0

FooView如果使用that subclasses创建了 Single View 应用程序UIView,然后执行

NSLog(@"hello");

in drawRect,然后打印出来。

如果我创建一个CALayer被调用的子类CoolLayer,并将这个方法添加到FooView.m

+(Class) layerClass {
    return [CoolLayer class];
}

FooView.m在's的末尾drawRect,做一个

NSLog(@"layer's class is %@", self.layer.class);

然后CoolLayer被打印。所以现在视图的底层是CoolLayer.

但是当以下添加到CoolLayer.m

-(void) display {

}

这是自动调用以重绘图层的方法(类似于drawRect),然后没有NSLog打印任何内容。可能是应用程序进入了无限循环。(即使touchesBegan是打印出 NSLog 消息的我也没有打印)。如果断点设置在display,它会停在那里一次,但是当我继续程序时,它将永远不会再到达display。这有什么问题,如何解决?

4

3 回答 3

2

这听起来不像是无限循环。如果您处于无限循环中,您的应用程序将冻结,几秒钟后,跳板应用程序会因无响应而终止它。

在您的图层上调用 setNeedsDisplay 或 setNeedsDisplayInRect 以使其“变脏”并要求再次绘制。请注意,您不必再调用 setNeedsDisplay,因为重新渲染图层并将其内容推送到屏幕上需要大量工作。仅在某些内容发生更改时显示

于 2012-05-28T15:14:37.413 回答
2

图层的显示方法不会被再次调用,除非图层是脏的,即设置为需要重新显示。这通常是一件好事,这就是为什么您不会看到该方法被多次调用的原因。

此外,显示的正常实现将调用该drawInContext:方法。由于您在子类中覆盖它,drawRect:因此永远不会调用视图的方法。您需要复制 的标准行为,或者在您自己的实现中CALayer调用超类的方法。display

于 2012-05-28T15:36:16.377 回答
1

您在这里看不到无限循环。如果你是,正如邓肯所指出的那样,你最终会因为看门狗定时器或无限递归而崩溃,这在你在调试器中看到的堆栈跟踪中会立即显而易见。

如果您将 NSLog 放入 UIView 的-drawRect:方法中,然后使用您自己的自定义 CALayer 覆盖其默认图层类,该 CALayer-drawRect:将不再调用您的 UIView。绘图现在将由您的自定义支持层处理。

正如核心动画编程指南的“通过子类化提供 CALayer 内容-display”小节中所述,如果您想以某种方式contents为您的图层自定义 CGImageRef,您通常会在您的 CALayer 中覆盖。通常,-drawInContext:如果您想在您的 CALayer 中渲染自定义 Quartz 绘图,您将被覆盖。使您的覆盖-display方法完全空白,并且不向属性写入任何内容,这contents不是标准行为,因此您看到这样做的奇怪结果并不奇怪。

根据您最近的一系列问题,我强烈建议您停下来花一些时间阅读 Core Animation Programming Guide 并查看一些涉及 CALayers 的示例代码,然后再继续。

于 2012-05-28T22:20:24.957 回答