-
-
Save steipete/8df39fea0d39680a7a6b to your computer and use it in GitHub Desktop.
This is the code path that changed the status bar orientation on iOS 7: | |
* thread #1: tid = 0x698dbf, 0x00085830 WindowRotationIssue`-[AppDelegate application:willChangeStatusBarOrientation:duration:](self=0x7a041f90, _cmd=0x0137a18d, application=0x79e39cc0, newStatusBarOrientation=UIInterfaceOrientationPortraitUpsideDown, duration=0.80000000000000004) + 96 at AppDelegate.m:23, queue = 'com.apple.main-thread', stop reason = breakpoint 3.1 | |
* frame #0: 0x00085830 WindowRotationIssue`-[AppDelegate application:willChangeStatusBarOrientation:duration:](self=0x7a041f90, _cmd=0x0137a18d, application=0x79e39cc0, newStatusBarOrientation=UIInterfaceOrientationPortraitUpsideDown, duration=0.80000000000000004) + 96 at AppDelegate.m:23 | |
frame #1: 0x00bb6ab5 UIKit`-[UIApplication setStatusBarOrientation:animationParameters:notifySpringBoardAndFence:] + 242 | |
frame #2: 0x00bfa8e4 UIKit`-[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:isRotating:] + 4761 | |
frame #3: 0x00bf9646 UIKit`-[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:] + 82 | |
frame #4: 0x00bf9518 UIKit`-[UIWindow _setRotatableViewOrientation:updateStatusBar:duration:force:] + 117 | |
frame #5: 0x00bf95a0 UIKit`-[UIWindow _setRotatableViewOrientation:duration:force:] + 67 | |
frame #6: 0x00bf863a UIKit`__57-[UIWindow _updateToInterfaceOrientation:duration:force:]_block_invoke + 120 | |
frame #7: 0x00bf859c UIKit`-[UIWindow _updateToInterfaceOrientation:duration:force:] + 400 | |
frame #8: 0x00bf8cd6 UIKit`-[UIWindow _updateInterfaceOrientationFromDeviceOrientation:] + 1346 | |
frame #9: 0x00bf878d UIKit`-[UIWindow _updateInterfaceOrientationFromDeviceOrientationIfRotationEnabled:] + 94 | |
frame #10: 0x00bf8399 UIKit`-[UIWindow _handleDeviceOrientationChange:] + 122 | |
frame #11: 0x00188049 Foundation`__57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke + 40 | |
frame #12: 0x00797f04 CoreFoundation`__CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 20 | |
frame #13: 0x006efefb CoreFoundation`_CFXNotificationPost + 2859 | |
frame #14: 0x000c1e41 Foundation`-[NSNotificationCenter postNotificationName:object:userInfo:] + 98 | |
frame #15: 0x00e0b5cf UIKit`-[UIDevice setOrientation:animated:] + 295 | |
frame #16: 0x00bc64fb UIKit`-[UIApplication handleEvent:withNewEvent:] + 806 | |
frame #17: 0x00bc7555 UIKit`-[UIApplication sendEvent:] + 85 | |
frame #18: 0x00bb4250 UIKit`_UIApplicationHandleEvent + 683 | |
Things got quite a bit more complex in iOS 8: | |
(Notice the new _UIWindowRotationAnimationController) | |
* thread #1: tid = 0x69b266, 0x0009e830 WindowRotationIssue`-[AppDelegate application:willChangeStatusBarOrientation:duration:](self=0x7af199e0, _cmd=0x017c1468, application=0x7b312ea0, newStatusBarOrientation=UIInterfaceOrientationLandscapeRight, duration=0) + 96 at AppDelegate.m:23, queue = 'com.apple.main-thread', stop reason = breakpoint 3.1 | |
* frame #0: 0x0009e830 WindowRotationIssue`-[AppDelegate application:willChangeStatusBarOrientation:duration:](self=0x7af199e0, _cmd=0x017c1468, application=0x7b312ea0, newStatusBarOrientation=UIInterfaceOrientationLandscapeRight, duration=0) + 96 at AppDelegate.m:23 | |
frame #1: 0x00ebed3f UIKit`-[UIApplication setStatusBarOrientation:animationParameters:notifySpringBoardAndFence:] + 248 | |
frame #2: 0x00f13cc6 UIKit`__78-[UIWindow _rotateWindowToOrientation:updateStatusBar:duration:skipCallbacks:]_block_invoke + 329 | |
frame #3: 0x013f7062 UIKit`__58-[_UIWindowRotationAnimationController animateTransition:]_block_invoke + 45 | |
frame #4: 0x013f7019 UIKit`-[_UIWindowRotationAnimationController animateTransition:] + 475 | |
frame #5: 0x00f1110f UIKit`-[UIWindow _rotateToBounds:withAnimator:transitionContext:] + 877 | |
frame #6: 0x00f13a21 UIKit`-[UIWindow _rotateWindowToOrientation:updateStatusBar:duration:skipCallbacks:] + 2143 | |
frame #7: 0x00f158a8 UIKit`-[UIWindow _setRotatableClient:toOrientation:applyTransformToWindow:updateStatusBar:duration:force:isRotating:] + 6839 | |
frame #8: 0x00f13120 UIKit`-[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:isRotating:] + 128 | |
frame #9: 0x00f13099 UIKit`-[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:] + 84 | |
frame #10: 0x00f12e7f UIKit`-[UIWindow _setRotatableViewOrientation:updateStatusBar:duration:force:] + 138 | |
frame #11: 0x00f12fec UIKit`-[UIWindow _setRotatableViewOrientation:duration:force:] + 68 | |
frame #12: 0x00f11cba UIKit`__57-[UIWindow _updateToInterfaceOrientation:duration:force:]_block_invoke + 130 | |
frame #13: 0x00f11c17 UIKit`-[UIWindow _updateToInterfaceOrientation:duration:force:] + 425 | |
frame #14: 0x00f124d8 UIKit`-[UIWindow _updateInterfaceOrientationFromDeviceOrientation:] + 1397 | |
frame #15: 0x00f11f5c UIKit`-[UIWindow _updateInterfaceOrientationFromDeviceOrientationIfRotationEnabled:] + 93 | |
frame #16: 0x00f119fb UIKit`-[UIWindow _handleDeviceOrientationChange:] + 122 | |
frame #17: 0x0012bc49 Foundation`__57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke + 40 | |
frame #18: 0x008bf4a4 CoreFoundation`__CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 20 | |
frame #19: 0x007ad03b CoreFoundation`_CFXNotificationPost + 3051 | |
frame #20: 0x0011b246 Foundation`-[NSNotificationCenter postNotificationName:object:userInfo:] + 98 | |
frame #21: 0x01187040 UIKit`-[UIDevice setOrientation:animated:] + 307 | |
frame #22: 0x00ed2f09 UIKit`-[UIApplication handleEvent:withNewEvent:] + 1364 | |
frame #23: 0x00ed34ac UIKit`-[UIApplication sendEvent:] + 85 | |
frame #24: 0x00ebbbe3 UIKit`_UIApplicationHandleEvent + 704 |
I have not gotten windows to deallocate easily in iOS8 at all if they have presented view controllers. I think that is a separate issue than this gist though. It seems any presented view controller has an inherent retain loop with the window, and dismissing the view controllers seems to be the only way to get them removed.
There is a separate problem with UISplitViewController, in that it installs a private _shouldPreventRotationHook block in the UIWindow, which has a strong retain to the UISplitViewController, and does not clean it up (nor does UIWindow release it when the window gets dealloced). That sounds like it might be the same issue (it would take another UISplitViewController to overwrite the original block). I think that may have been fixed in iOS 8.3, at least the UIWindow dealloc portion.
@grzegorzduda you're correct, I've been seeing this since 8.0. Specifically, a UISplitViewController with a presented view controller leaking both the SplitViewController and the presented view controller, until the next time another UISplitViewController (not just any UIViewController!) becomes the window's root view controller.