Приложение аварийно завершает работу при вызове setNeedsDisplay для пользовательской кнопки

У меня есть пользовательская кнопка, приложение случайно вылетает при вызове setNeedsDisplay. Как исправить этот сбой?

class MyVC: UIViewController {

    @IBOutlet weak var customButton: CustomButton!

    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)

        self.customButton.setNeedsDisplay() // Random crash here
    }
}

class CustomButton: UIButton {
    // ....

    override func setNeedsDisplay() {
        self.imageEdgeInsets = UIEdgeInsets(top: 0, left: UIScreen.main.bounds.size.width-29, bottom: 4.0, right: 0)
    }
}

Журнал сбоев

Сбой: com.apple.main-thread EXC_BREAKPOINT 0x0000000104fb3f48

Предполагая, что ваша строка, которая дает сбой, должна на самом деле читать:


person Kamil    schedule 01.09.2019    source источник
comment
вы разместили код _1_ и сказали, что это строка, которая дает сбой. Однако вы не показываете определение _2_. Это должно быть _3_, а не _4_? Не перефразируйте свой код — публикуйте фактический код.   -  person rmaddy    schedule 02.09.2019
comment
Я обновил вопрос, это customButton.   -  person Duncan C    schedule 02.09.2019
comment
Вы не опубликовали сообщение об ошибке. Трассировка стека не имеет значения, поскольку вы уже указали проблемную строку.   -  person Kamil    schedule 02.09.2019
comment
Да, именно это я и подозревал, что customButton равен нулю. Означает ли это, что эта кнопка не инициализируется в раскадровке при вызове этой функции? Нужно ли охранять это заявление, чтобы решить эту проблему?   -  person rmaddy    schedule 02.09.2019


Ответы (1)


Проблема, скорее всего, в том, что customButton равно нулю. Вы объявили customButton как неявно развернутый необязательный параметр. Это означает, что компилятор разворачивает его для вас, когда вы пытаетесь сослаться на него. Попробуйте добавить:

self.customButton.setNeedsDisplay() // Random crash here

И посмотрите журнал отладки. Я предполагаю, что вы увидите что-то вроде:

print("self.customButton = \(self.customButton?)")
self.customButton.setNeedsDisplay() // Random crash here

self.customButton = Необязательно (ноль)

Редактируйте свой вопрос, чтобы включить полное сообщение об ошибке из-за сбоя.

person Duncan C    schedule 01.09.2019
comment
Когда контроллер представления создается из раскадровки/xib, его представления не загружаются немедленно. Я давно не использовал _1_ и не помню, вызывается ли он до загрузки представлений целевого контроллера представления или нет. Это был бы хороший случай для необязательной цепочки: _2_ (Обратите внимание на добавленный вопросительный знак.) В необязательной цепочке, если необязательное развертывание равно nil, метод не вызывается, но выполнение продолжается со следующей строки. - person Kamil; 02.09.2019
comment
Большое спасибо за подробное объяснение. Я исправлю это так, как вы объяснили. - person Duncan C; 02.09.2019
comment
Сбой: com.apple.main-thread 0 myapp 0x104fb3f48 MyVC.viewWillTransition(to:with:) + 63 (MyVC.swift:63) 1 myapp
0x104fb3f88 @objc MyVC.viewWillTransition(to:with:) () 2 UIKitCore 0x1ee286708 - [UIViewController viewWillTransitionToSize: withTransitionCoordinator:] + 868 3 UIKitCore 0x1ee1e596c - [UINavigationController viewWillTransitionToSize: withTransitionCoordinator:] + 84 4 UIKitCore 0x1ee286708 - [UIViewController viewWillTransitionToSize: withTransitionCoordinator:] + 868 5 UIKitCore 0x1ee1b46dc - [UITabBarController viewWillTransitionToSize: withTransitionCoordinator:] + 48 6 UIKitCore 0x1ee27ba18 +[UIViewController _performWithoutDeferringTransitions:] + 112 7 UIKitCore 0x1ee292a24 -[UIViewController(AdaptiveSizing) _window:viewWillTransitionToSize:withTransitionCoordinator:] + 580 8 UIKitCore 0x1ee8537-40x1ee853618 - [UIWindow _rotateToBounds: withAnimator: transitionContext:] + 412 11 UIKitCore 0x1ee855e24 - [UIWindow _rotateWindowToOrientation :updateStatusBar:duration:skipCallbacks:] + 1184 12 UIKitCore 0x1ee8564d8 -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:isRotating:] + 516 13 UIKitCore 0x1ee8558d8 -[UIWindow _setRotatableViewCoreuration1 +UKStatusBar:dd8 0x1ee854584 __57-[UIWindow _updateToInterfaceOrientation:duration:force:]_block_invoke + 124 15 UIKitCore 0x1ee854488 -[UIWindow _updateToInterfaceOrientation:duration:force:] + 560 16 UIKitCore 0x1ee0dcfe0 -[_UICanvasMetricsCalculator u pdateMetricsOnWindows:animated:] + 624 17 UIKitCore
0x1ee0e1990 -[_UICanvas _computeMetrics:] + 180 18 UIKitCore
0x1eeca08f0 +[UIView(Animation) PerformWithoutAnimation:] + 104 19 UIKitCore 0x1ee0e0e04a8 -[_UICanvas _computeMetrics] 172 20 UIKitCore 0x1ee821b0c - [UIApplication _createSnapshotContextForScene: withName: performLayoutWithSettings:] + 404 21 UIKitCore 0x1ee8232f0 __65- [UIApplication _performSnapshotsWithAction: forScene: завершение:] _ block_invoke_2 + 124 22 FrontBoardServices 0x1c4b51768 - [FBSSceneSnapshotAction _executeNextRequest] + 256 23 FrontBoardServices 0x1c4b517b8 - [FBSSceneSnapshotAction _executeNextRequest ] + 336 24 FrontBoardServices 0x1c4b51358 -[FBSSceneSnapshotAction executeRequestsWithHandler:completionHandler:expirationHandler:] + 276 25 UIKitCore 0x1ee823220 __65-[UIApplication _performSnaps hotsWithAction: forScene: завершение:] _ block_invoke + 268 26 UIKitCore 0x1ee822848 - [UIApplication _beginSnapshotSessionForScene: withSnapshotBlock:] + 744 27 UIKitCore 0x1ee822f74 - [UIApplication _performSnapshotsWithAction: forScene: завершение:] + 208 28 UIKitCore 0x1ee822e40 - [UIApplication _handleSnapshotAction: forScene: завершение: ] + 156 29 UIKitCore 0x1ee81e724 __71- [UIApplication _handleSnapshotAction: forScene: deactivationCompletion:] _ block_invoke + 332 30 UIKitCore 0x1ee81e540 - [UIApplication _handleSnapshotAction: forScene: deactivationCompletion:] + 340 31 UIKitCore 0x1ee0d9f58 __98 - [__ UICanvasLifecycleMonitor_Compatability deactivateEventsOnly: withContext: forceExit: завершение: ]_block_invoke. 261 + 820 32 UIKitCore 0x1ee8220ac _runAfterCACommitDeferredBlocks + 296 33 UIKitCore 0x1ee810bfc _cleanUpAfterCAFlushAndRunDeferredBlocks + 352 34 UIKitCore 0x1ee83da6c _afterCACommitHandler + 116 35 CoreFoundation 0x1c212ed08 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION + 32 36 CoreFoundation 0x1c2129a30 __CFRunLoopDoObservers + 412 37 CoreFoundation 0x1c2129fac __CFRunLoopRun + 1 228 38 CoreFoundation 0x1c21297c0 CFRunLoopRunSpecific + 436 39 GraphicsServices
0x1c432a79c GSEventRunModal + 104 40 UIKitCore
0x1ee816c38 UIApplicationMain + 212 41 myapp
0x104db7454 main + 20 (ProfileVC.swift:20) 42 libdyld.dylib
0x1c1bed8e0 start + 4 - person Kamil; 02.09.2019