我有一个自定义的UIView,其中包括一个自定义的CALayer来绘制一些形状和播放动画。在该应用程序的最后几个版本中,它工作正常,没有任何问题。最新发布的版本一直在iOS 9上崩溃,但可以在其他版本的iOS上运行。
Crashlytics上的错误日志显示EXC_BAD_ACCESS KERN_INVALID_ADDRESS,堆栈跟踪表明自定义视图的构造函数是崩溃的根源。
这里有一个简化的例子,它在我的iOS 9 iPad Mini 2设备上崩溃,但在我的新机型上可以正常工作。
import UIKit
class CustomView: UIView {
private let customLayer: CustomLayer = CustomLayer()
init(color: UIColor) {
super.init(frame: .zero)
self.customLayer.color = color
}
required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") }
override func didMoveToWindow() {
super.didMoveToWindow()
setupAnimation()
}
private func setupAnimation() {
...
}
}
fileprivate class CustomLayer: CALayer {
var color: UIColor = .white
override init() { super.init() }
override init(layer: Any) { super.init(layer: layer) }
required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") }
override func draw(in ctx: CGContext) {
// Some CoreGraphics drawing commands
}
}发布于 2020-05-26 14:54:40
在写完这个例子后不久,我在苹果开发者论坛上找到了一个解释:https://forums.developer.apple.com/thread/131551
这个问题似乎是由最新的Xcode更新引起的。目前我使用的是Xcode11.4.1,崩溃发生在iOS 9上。代码在上一版本的集成开发环境中工作没有任何问题。
根据论坛的讨论,该错误特别与CALayer子类的自定义属性相关。作为一种解决办法,我在自定义层的构造函数中移动了属性初始化,现在它可以工作了:
class CustomView: UIView {
private let customLayer: CustomLayer
init(color: UIColor) {
self.customLayer.color = CustomLayer(color: color)
super.init(frame: .zero)
}
...
}
fileprivate class RayLayer: CALayer {
private let color: UIColor
init(color: UIColor) {
self.color = color
super.init()
}
override init(layer: Any) {
self.color = .white
super.init(layer: layer)
}
...
}发布于 2021-08-26 13:44:51
在将一些类转换为swift之后,我们也有了这个功能。仅限iOS 9。我们的解决方法是使用计算属性,并从中获取/设置值。在我们的例子中,使用objc关联的对象值,但也可以是字典/缓存或任何外部构造,这些构造不必存储在getter子类实例(自定义属性)中,但可以通过计算属性CALayer /setter访问。
https://stackoverflow.com/questions/62016268
复制相似问题