我正在尝试使用一系列 CALayer 作为 View 的子层,该 View 需要比平时更精细的绘图。我以前一直在使用 CATiledLayer
,我认为使用子层会更容易,即使不是同样挑剔的话。我想我执行了一个 [self.layer addSublayer:sublayer]
,设置了那个新子层的委托(delegate),然后我在 drawLayer:inContext:
方法中绘制了我想要的所有内容。但令我大吃一惊的是,我的应用程序在 addSubview:
(没有 IB)或调用堆栈的更高位置(使用 IB 时)崩溃。
根据文档...
CALayer reference似乎完全决定了我在做什么,但每次都会崩溃:
In iOS, if the layer is associated with a UIView object, this property must be set to the view that owns the layer.
但显然,我搞砸了。值得庆幸的是,它很容易重现。你能给我解释一下我应该如何使用带有委托(delegate)分配的子层来接收正确的 drawLayer:inContext:
调用而不会崩溃吗?
重现步骤
将其放入使用 Interface Builder 显示在屏幕上的自定义 View 的类中(或将初始化重写为 initWithFrame:
):
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
CALayer *sublayer = [CALayer layer];
sublayer.frame = self.layer.bounds;
// Disable or enable this next line to
// resolve or trigger an EXC_BAD_ACCESS crash.
//
sublayer.delegate = self;
[self.layer addSublayer:sublayer];
[self.layer setNeedsDisplay];
}
return self;
}
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
CGContextSetFillColorWithColor(ctx, [[UIColor greenColor] CGColor]);
CGContextFillRect(ctx, self.bounds);
}
如果您运行此代码,您的应用程序将会崩溃。注意 sublayer.delegate = self
行。如果您禁用那个,您的应用程序将运行,但永远不会为该子层调用 drawLayer:inContext:
方法。
我做错了什么?
最佳答案
这不起作用,因为您正在子类化的 UIView(我假设它是一个 UIView)已经是它自己的 CALayer 的委托(delegate),它不能同时是多个 CALayer 的委托(delegate)。这篇文章有更多细节:
关于objective-c - 将委托(delegate)分配给 CALayer 的子层会抛出 EXC_BAD_ACCESS?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9386397/