Reputation: 887
I have a custom UIView that includes a custom CALayer to draw some shapes and play an animation. For the last couple releases of the app it was working without any issue. The last published version is consistently crashing on iOS 9, but works on other versions of iOS.
The error log on Crashlytics shows EXC_BAD_ACCESS KERN_INVALID_ADDRESS
and the stack trace indicates the constructor of the custom view as the root of the crash.
Here's a simplified example, which crashes on my iOS 9 iPad Mini 2 device but works on my newer models.
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
}
}
Upvotes: 0
Views: 271
Reputation: 41
We are having this as well after converting some classes to swift. Only iOS 9. Our workaround is to use computed properties, and get/set the values from there. In our case using objc associated object values, but could be as well a dictionary/cache or whatever external construct that doesn't have to be stored in the CALayer subclass instance (custom property), but accessible via the computed properties getters/setters.
Upvotes: 1
Reputation: 887
Shortly after writing this example I've found an explanation on the Apple Developer Forums: https://forums.developer.apple.com/thread/131551
It seems like this issue is caused by latest Xcode update. Currently I'm using Xcode 11.4.1 and the crash happens consistently on iOS 9. The code was working in the previous version of the IDE without any problems.
Based on the forum discussion, the bug is specifically related to the custom properties of a CALayer subclass. As a workaround, I moved the property initialisation in the constructor of the custom layer and now it works:
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)
}
...
}
Upvotes: 0