将委托分配给CALayer的子图层会抛出EXC_BAD_ACCESS? [英] Assigning a delegate to a CALayer's sublayer throws EXC_BAD_ACCESS?

查看:172
本文介绍了将委托分配给CALayer的子图层会抛出EXC_BAD_ACCESS?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to use a series of CALayers as sublayers to a view that needs a little more fine grained drawing than usual. I've been using CATiledLayer before, and I thought using sublayers would be easier, if not equally finicky. I figured I perform a [self.layer addSublayer:sublayer], set the delegate of that new sublayer and then I draw all I want in the drawLayer:inContext: method. But to my great surprise, my app crashes on addSubview: (without IB) or somewhere higher up the call stack (when using IB).

CALayer参考


在iOS中,如果图层与一个UIView对象,此属性必须设置为拥有图层的视图。

In iOS, if the layer is associated with a UIView object, this property must be set to the view that owns the layer.

但是显然,东西了。幸运的是,它很容易重现。你能解释一下我应该如何使用sublayers与委托分配接收正确的 drawLayer:inContext:调用没有崩溃?

But obviously, I'm screwing something up. Thankfully, it's easily reproducible. Can you explain to me how I should be using sublayers with delegate assignments to receive the right drawLayer:inContext: calls without crashing?

把这个放在带有Interface Builder的自定义视图的类中(或重写要调用的init initWithFrame:):

Put this in the class of a custom view put on screen with Interface Builder (or rewrite the init to be called 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:方法从未调用该子图层。

If you run this code, your app will crash. Mind the sublayer.delegate = self line. If you disable that one, your app will run, but the drawLayer:inContext: method is never called for that sublayer.

我做错了什么?

推荐答案

因为你是子类化的UIView(我假设它是一个UIView)已经是它自己的CALayer的委托,它不能同时是多个CALayer的委托。此信息有一些详细信息:

This does not work because the UIView you are subclassing (I assume it is a UIView) already is the delegate of its own CALayer, it cannot be the delegate of more than one CALayer at once. This post has some more details:

使用CALayer委托

这篇关于将委托分配给CALayer的子图层会抛出EXC_BAD_ACCESS?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆