From f09c4d098643d1ab5691a673f443847332073cb1 Mon Sep 17 00:00:00 2001 From: Constantine Loutas <748631+CLoutas@users.noreply.github.com> Date: Sun, 23 Aug 2020 09:39:02 +0100 Subject: [PATCH] Fix Implicitly Unwrapped Optional Crash The presentationController variable is declared as an implicitly unwrapped optional (line 38): private var presentationController: SideMenuPresentationController! There are situations where this will cause a crash, as the property could be null while transitioning: Crashed: com.apple.main-thread 0 MyApp 0x102c57398 closure #1 in SideMenuNavigationController.viewWillTransition(to:with:) + 107 (SideMenuAnimationController.swift:107) 1 MyApp 0x102c573d0 thunk for @escaping @callee_guaranteed (@guaranteed UIViewControllerTransitionCoordinatorContext) -> () + 4336055248 (:4336055248) 2 UIKitCore 0x1b67c58f4 -[_UIViewControllerTransitionCoordinator _applyBlocks:releaseBlocks:] + 276 3 UIKitCore 0x1b67c21b4 -[_UIViewControllerTransitionContext __runAlongsideAnimations] + 284 4 UIKitCore 0x1b67d9b38 -[_UIWindowAnimationController animateTransition:] + 344 5 UIKitCore 0x1b6e48044 -[UIWindow _adjustSizeClassesAndResizeWindowToFrame:] + 964 6 UIKitCore 0x1b6e546b4 -[UIWindow _resizeWindowFrameToSceneBoundsIfNecessary] + 252 7 UIKitCore 0x1b6e4a26c __78-[UIWindow _rotateWindowToOrientation:updateStatusBar:duration:skipCallbacks:]_block_invoke + 408 8 UIKitCore 0x1b67da1e8 __58-[_UIWindowRotationAnimationController animateTransition:]_block_invoke_2 + 180 9 UIKitCore 0x1b72d0e48 +[UIView(Internal) _performBlockDelayingTriggeringResponderEvents:forScene:] + 212 10 UIKitCore 0x1b67d9fd4 __58-[_UIWindowRotationAnimationController animateTransition:]_block_invoke + 180 11 UIKitCore 0x1b67d9e98 -[_UIWindowRotationAnimationController animateTransition:] + 524 12 UIKitCore 0x1b6e478c4 -[UIWindow _rotateToBounds:withAnimator:transitionContext:] + 624 13 UIKitCore 0x1b6e49f74 -[UIWindow _rotateWindowToOrientation:updateStatusBar:duration:skipCallbacks:] + 1436 14 UIKitCore 0x1b6e4a4b0 -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:isRotating:] + 404 15 UIKitCore 0x1b6e49844 -[UIWindow _setRotatableViewOrientation:updateStatusBar:duration:force:] + 132 16 UIKitCore 0x1b66bf2dc -[_UIFullscreenPresentationController _placeCounterRotationViewWithView:inWindow:fromOrientation:toOrientation:force:] + 520 17 UIKitCore 0x1b66bf010 -[_UIFullscreenPresentationController _adjustOrientationIfNecessaryInWindow:forViewController:preservingViewController:] + 908 18 UIKitCore 0x1b66b45ec -[UIPresentationController _presentWithAnimationController:interactionController:target:didEndSelector:] + 900 19 UIKitCore 0x1b67a8590 -[UIViewController _presentViewController:modalSourceViewController:presentationController:animationController:interactionController:completion:] + 1416 20 UIKitCore 0x1b67a9f74 -[UIViewController _presentViewController:withAnimationController:completion:] + 4212 21 UIKitCore 0x1b67ac540 __63-[UIViewController _presentViewController:animated:completion:]_block_invoke + 108 22 UIKitCore 0x1b67aca94 -[UIViewController _performCoordinatedPresentOrDismiss:animated:] + 528 23 UIKitCore 0x1b67ac48c -[UIViewController _presentViewController:animated:completion:] + 212 24 UIKitCore 0x1b67ac720 -[UIViewController presentViewController:animated:completion:] + 176 25 UIKitCore 0x1b6f6f9b8 __74-[UIStoryboardPresentationSegueTemplate newDefaultPerformHandlerForSegue:]_block_invoke + 148 26 UIKitCore 0x1b6f75a18 -[UIStoryboardSegueTemplate _performWithDestinationViewController:sender:] + 296 27 UIKitCore 0x1b6f758bc -[UIStoryboardSegueTemplate _perform:] + 96 28 UIKitCore 0x1b6f75b98 -[UIStoryboardSegueTemplate perform:] + 164 29 UIKitCore 0x1b6e086c0 -[UIApplication sendAction:to:from:forEvent:] + 100 30 UIKitCore 0x1b6479858 __45-[_UIButtonBarTargetAction _invoke:forEvent:]_block_invoke + 84 31 UIKitCore 0x1b64796e4 -[_UIButtonBarTargetAction _invoke:forEvent:] + 256 32 UIKitCore 0x1b6e086c0 -[UIApplication sendAction:to:from:forEvent:] + 100 33 UIKitCore 0x1b67f0b30 -[UIControl sendAction:to:forEvent:] + 208 34 UIKitCore 0x1b67f0e98 -[UIControl _sendActionsForEvents:withEvent:] + 400 35 UIKitCore 0x1b67efeb0 -[UIControl touchesEnded:withEvent:] + 520 36 UIKitCore 0x1b6e43b08 -[UIWindow _sendTouchesForEvent:] + 1024 37 UIKitCore 0x1b6e452f0 -[UIWindow sendEvent:] + 3548 38 UIKitCore 0x1b6e2045c -[UIApplication sendEvent:] + 348 39 UIKitCore 0x1b6ea3a54 __dispatchPreprocessedEventFromEventQueue + 6688 40 UIKitCore 0x1b6ea6648 __handleEventQueueInternal + 5368 41 UIKitCore 0x1b6e9e578 __handleHIDEventFetcherDrain + 144 42 CoreFoundation 0x1b2c39af4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 28 43 CoreFoundation 0x1b2c39a48 __CFRunLoopDoSource0 + 84 44 CoreFoundation 0x1b2c39198 __CFRunLoopDoSources0 + 196 45 CoreFoundation 0x1b2c33f38 __CFRunLoopRun + 796 46 CoreFoundation 0x1b2c338f4 CFRunLoopRunSpecific + 480 47 GraphicsServices 0x1bd04a604 GSEventRunModal + 164 48 UIKitCore 0x1b6e07358 UIApplicationMain + 1944 49 MyApp 0x102921628 main + 15 (AppDelegate.swift:15) 50 libdyld.dylib 0x1b2aaf2dc start + 4 By making it a normal optional, we can avoid such crashes. --- Pod/Classes/SideMenuAnimationController.swift | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Pod/Classes/SideMenuAnimationController.swift b/Pod/Classes/SideMenuAnimationController.swift index b484b8ca..aa6ff8d3 100644 --- a/Pod/Classes/SideMenuAnimationController.swift +++ b/Pod/Classes/SideMenuAnimationController.swift @@ -35,7 +35,7 @@ internal final class SideMenuAnimationController: NSObject, UIViewControllerAnim private weak var containerView: UIView? private let leftSide: Bool private weak var originalSuperview: UIView? - private var presentationController: SideMenuPresentationController! + private var presentationController: SideMenuPresentationController? private unowned var presentedViewController: UIViewController? private unowned var presentingViewController: UIViewController? weak var delegate: SideMenuAnimationControllerDelegate? @@ -104,7 +104,7 @@ internal final class SideMenuAnimationController: NSObject, UIViewControllerAnim } func layout() { - presentationController.containerViewWillLayoutSubviews() + presentationController?.containerViewWillLayoutSubviews() } } @@ -131,25 +131,25 @@ private extension SideMenuAnimationController { // prevent any other menu gestures from firing containerView?.isUserInteractionEnabled = false if presenting { - presentationController.presentationTransitionWillBegin() + presentationController?.presentationTransitionWillBegin() } else { - presentationController.dismissalTransitionWillBegin() + presentationController?.dismissalTransitionWillBegin() } } func transition(presenting: Bool) { if presenting { - presentationController.presentationTransition() + presentationController?.presentationTransition() } else { - presentationController.dismissalTransition() + presentationController?.dismissalTransition() } } func transitionDidEnd(presenting: Bool, completed: Bool) { if presenting { - presentationController.presentationTransitionDidEnd(completed) + presentationController?.presentationTransitionDidEnd(completed) } else { - presentationController.dismissalTransitionDidEnd(completed) + presentationController?.dismissalTransitionDidEnd(completed) } containerView?.isUserInteractionEnabled = true }