Пользовательский рисунок UIView вылетает на iOS 9, но работает в других системах - PullRequest
0 голосов
/ 26 мая 2020

У меня есть настраиваемый UIView, который включает настраиваемый CALayer для рисования некоторых фигур и воспроизведения анимации. Последние пару выпусков приложения оно работало без проблем. Последняя опубликованная версия постоянно дает сбой на iOS 9, но работает с другими версиями iOS.

В журнале ошибок на Crashlytics отображается EXC_BAD_ACCESS KERN_INVALID_ADDRESS, а трассировка стека указывает конструктор настраиваемого представления как the root cra sh.

Вот упрощенный пример, который дает сбой на моем устройстве iPad Mini 2 iOS 9, но работает на моих новых моделях.

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
    }


}

1 Ответ

0 голосов
/ 26 мая 2020

Вскоре после написания этого примера я нашел объяснение на форумах разработчиков Apple: https://forums.developer.apple.com/thread/131551

Похоже, эта проблема вызвана последним обновлением Xcode. В настоящее время я использую Xcode 11.4.1, и cra sh постоянно происходит на iOS 9. Код работал в предыдущей версии IDE без каких-либо проблем.

На основании обсуждения на форуме, ошибка конкретно связана с пользовательскими свойствами подкласса 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)
    }
    ...
}
...