【问题标题】:Assigning a delegate to a CALayer's sublayer throws EXC_BAD_ACCESS?将委托分配给 CALayer 的子层会引发 EXC_BAD_ACCESS?
【发布时间】:2012-03-12 06:50:33
【问题描述】:

我正在尝试使用一系列 CALayers 作为视图的子层,该视图需要比平时更细粒度的绘图。我以前一直在使用CATiledLayer,我认为使用子层会更容易,如果不是同样挑剔的话。我想我执行[self.layer addSublayer:sublayer],设置新子层的委托,然后在drawLayer:inContext: 方法中绘制我想要的所有内容。但令我大吃一惊的是,我的应用在 addSubview:(没有 IB)或调用堆栈更高的位置(使用 IB 时)崩溃。

根据文档...

CALayer reference 似乎准确地指示了我在做什么,但它每次都会崩溃:

在 iOS 中,如果图层与 UIView 对象相关联,则必须将此属性设置为拥有该图层的视图。

但显然,我搞砸了。值得庆幸的是,它很容易重现。你能向我解释一下我应该如何使用具有委托分配的子层来接收正确的drawLayer:inContext: 调用而不会崩溃?

重现步骤

将其放入使用 Interface Builder 放在屏幕上的自定义视图的类中(或重写 init 以调用 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: 方法。

我做错了什么?

【问题讨论】:

    标签: objective-c cocoa-touch delegates drawing calayer


    【解决方案1】:

    这不起作用,因为您正在继承的 UIView(我假设它是 UIView)已经是它自己的 CALayer 的委托,它不能同时是多个 CALayer 的委托。这篇文章有更多细节:

    Using CALayer Delegate

    【讨论】:

    • 感谢您的帖子,我找不到那个,它也没有出现在“相关”列中。关于为什么 Apple 不允许双重委托分配的任何线索?谢谢!
    猜你喜欢
    • 2011-09-15
    • 2015-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-23
    • 1970-01-01
    • 2011-01-02
    相关资源
    最近更新 更多