如何为CALayer设置代理?

3
我正在尝试设置CALayer的委托以便使用draw(_:in:)文档描述了如何操作。但是,一旦我设置了代理,就会出现运行时错误:

Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT)

以下是生成错误的代码。在Xcode 8.2.1中替换Single View Application模板中的ViewController.swift

import UIKit
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let myLayer = CALayer()
        myLayer.delegate = LayerDelegate()
        view.layer.addSublayer(myLayer)
    }
}

class LayerDelegate: NSObject, CALayerDelegate {
}

2
CALayerdelegate属性是weak类型的,所以如果将一个新对象赋值给它,会导致该对象立即被释放。不过,我不确定这是否是你异常的源头... - Robert
根据这个答案:https://dev59.com/LWIk5IYBdhLWcg3wBqKW#19652248,EXC_I386_GPFLT 明显是指“通用保护故障”,这是 x86 的方式告诉你“你做了一些不允许的事情”。它通常并不意味着你访问了超出内存边界的内容,但可能是你的代码越界并导致使用了错误的代码/数据,从而造成某种形式的保护违规。 - Ali Abbas
1
你尝试过这个代码吗?class ViewController: UIViewController { let layerDelegate = LayerDelegate() override func viewDidLoad() { ... myLayer.delegate = layerDelegate }} - Yannick
1
文档示例将委托保存在属性中的强引用中。也许这是一个先决条件,而weak引用实际上是一个unowned引用,因此您会因为委托被释放而崩溃。 - Cristik
1
@Yannick 那个方法有效。谢谢!我已经将其作为答案,但如果你创建自己的答案,我会接受你的。 - Robert
显示剩余2条评论
1个回答

2

由于没有强引用,该对象从内存中删除。正如其他人@Robert指出的那样,CALayerdelegateweak的,一旦您离开作用域(即viewDidLoad()函数),该对象将从内存中删除。

您需要确保它不会被释放。您可以向您的类添加一个属性。这将与类同生共死。

class ViewController: UIViewController {
    let layerDelegate = LayerDelegate()
    override func viewDidLoad() {
        super.viewDidLoad()
        let myLayer = CALayer()
        myLayer.delegate = layerDelegate
        view.layer.addSublayer(myLayer)
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接