ios - CALayercornerRadius 导致应用程序间歇性崩溃

标签 ios swift xcode app-store calayer

请帮助解决此错误。这让我困惑了几天。该错误仅在少数选定设备上发生,但我无法在我的设备上模拟该行为。
我有一个向用户显示通知的应用程序。通知导航 Controller 有一个标签,它使用下面的类来设置一些属性

class LabelPaddingNotifications: UILabel {
var insets = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)


func padding(_ top: CGFloat, _ bottom: CGFloat, _ left: CGFloat, _ right: CGFloat) {
    self.frame = CGRect(x: 0, y: 0, width: self.frame.width + left + right, height: self.frame.height + top + bottom)
    insets = UIEdgeInsets(top: top, left: left, bottom: bottom, right: right)
}

override func drawText(in rect: CGRect) {
    super.drawText(in: rect.inset(by: insets))
}

override var intrinsicContentSize: CGSize {
    get {
        var contentSize = super.intrinsicContentSize
        contentSize.height += insets.top + insets.bottom + 50
        contentSize.width += insets.left + insets.right
        return contentSize
    }
}}
该应用程序有时会在以下行崩溃。不过,我无法在我的设备或模拟器上模拟行为。下面的代码在类的viewDidLoad中
labelNotification.layer.cornerRadius = _smallButtonCornerRadius
并且导出定义为
@IBOutlet var labelNotification: LabelPadding!
小半径在常量文件中定义如下
let _smallButtonCornerRadius : CGFloat = 7
我也对 CALayer 进行了扩展,如下所示
extension CALayer {

func shake(duration: TimeInterval = TimeInterval(0.5)) {

    let animationKey = "shake"
    removeAnimation(forKey: animationKey)

    let kAnimation = CAKeyframeAnimation(keyPath: "transform.translation.x")
    kAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
    kAnimation.duration = duration

    var needOffset = frame.width * 0.15,
    values = [CGFloat]()

    let minOffset = needOffset * 0.1

    repeat {

        values.append(-needOffset)
        values.append(needOffset)
        needOffset *= 0.5
    } while needOffset > minOffset

    values.append(0)
    kAnimation.values = values
    add(kAnimation, forKey: animationKey)
}

func pulsate() {
    let pulse = CASpringAnimation(keyPath: "transform.scale")
    pulse.duration = 0.5
    pulse.fromValue = 0.95
    pulse.toValue = 1.0
    pulse.autoreverses = false
    pulse.repeatCount = 0
    pulse.initialVelocity = 0.5
    pulse.damping = 1.0
    add(pulse, forKey: nil)
}
}
Crashlytics 向我显示以下错误

The stack trace indicates that heap corruption may have caused your app to crash. Memory corruption can occur pretty easily from freeing a dangling pointer, a thread race, or bad pointer arithmetic. The important thing to keep in mind is that the resulting crash may happen long after the initial corruption. As a result, the stack trace for this crash might not provide any clues to the location of the bug in your code. However, you can still fix memory issues with tools from Apple. For speedy resolution of memory corruption issues, we recommend regularly auditing your app with Xcode’s memory debugging facilities: Visual Memory Debugger, Zombies Instrument, Address Sanitizer, Thread Sanitizer and malloc diagnostics.


虽然 XCode 管理器中的崩溃在上面的行中向我显示了一个错误,但给了我以下信息
enter image description here
更新
在收到我在应用程序中设置的本地通知后,这个特定的 View Controller 会从 AppDelegate 文件中触发。它的代码如下
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: {
                if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "VCShowNotification") as? ShowNotificationVC {
                if let window = self.window, let rootViewController = window.rootViewController {
                    var currentController = rootViewController
                    while let presentedController = currentController.presentedViewController {
                        currentController = presentedController
                    }
                    let navController = UINavigationController(rootViewController: controller)
                    currentController.present(navController, animated: true, completion: nil)
                    //currentController.present(controller, animated: true, completion: nil)
                }
            }}
我现在更新了从我的 appdelegate 启动通知 Controller 的方法,方法是向它和主线程添加 1 秒的延迟。现在这会打开应用程序,但通知 Controller 不再出现在某些设备上。该应用程序已停止崩溃。我无法在我的设备上模拟错误,这就是为什么我真的在努力解决这个问题。

最佳答案

此类错误通常是由于线程不匹配造成的,也就是说,此 UI 代码在主线程中运行,但其他代码在辅助线程中更改其参数。
您可以添加观察者并对此进行测试:

// Note typing this in Stack so no way to see typos etc
@IBOutlet var labelNotification: LabelPadding! {
  didSet {
    assert(Thread.isMainThread)
    assert(LabelPadding != nil)
  }
}
在设置之前读取该属性的可能性很小,因此您可能希望将其重新定义为:
@IBOutlet var labelNotification: LabelPadding?
然后在每次使用中使用 guard :
guard let labelNotification = labelNotification else { return }
    

关于ios - CALayercornerRadius 导致应用程序间歇性崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62952570/

相关文章:

xcode - 不知道为什么switch控件总是发送false值

ios - IOS8 beta 中的共享扩展

xcode - 通用应用程序 - iPad View 加载,但我无法将任何 ImageView 链接到 UIImage 对象而不会出现错误

ios - AVAudioSession 无法识别来自蓝牙设备的音频

iOS UI - App Store 浏览部分过渡

Swift - 将两个 UITextFeild 的值相乘

ios - @IBInspectable 与枚举?

ios - 如何在XCode中获取不同iphone尺寸(4S、5、6)的app截图

xcode - 如何在 XCode 中移动代码行

ios - 自定义框架不工作 ios