Search code examples
objective-ciosxcodecocoa-touchxcode4

UINavigation Controller Memory Issue


I'm running into a problem with my app crashing as a result of non-existent view controllers. After upgrading to the latest version of Xcode and having device logs that symbolicate properly, my suspicions were confirmed. After clicking the back button on a page, popviewcontroller is called and the app crashes. Here's the exact error report from my system:

Thread 0 Crashed:
0   libobjc.A.dylib                 0x341fcc98 0x341fa000 + 11416
1   libobjc.A.dylib                 0x34206506 0x341fa000 + 50438
2   libobjc.A.dylib                 0x341fe040 0x341fa000 + 16448
3   Holler                          0x00010a06 0x1000 + 64006
4   Holler                          0x0000e504 0x1000 + 54532
5   UIKit                           0x00036f08 -[UIViewController view] + 104
6   UIKit                           0x000455e8 -[UIViewController contentScrollView] + 16
7   UIKit                           0x00045458 -[UINavigationController _computeAndApplyScrollContentInsetDeltaForViewController:] + 24
8   UIKit                           0x00045356 -[UINavigationController _layoutViewController:] + 18
9   UIKit                           0x00044e2e -[UINavigationController _startTransition:fromViewController:toViewController:] + 374
10  UIKit                           0x00044c3c -[UINavigationController _startDeferredTransitionIfNeeded] + 176
11  UIKit                           0x00044b80 -[UINavigationController viewWillLayoutSubviews] + 8
12  UIKit                           0x00044b1c -[UILayoutContainerView layoutSubviews] + 132
13  UIKit                           0x000055f4 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 20
14  CoreFoundation                  0x0000befc -[NSObject(NSObject) performSelector:withObject:] + 16

As I understand it, UINavigationController retains ownership of all the view controllers in its stack. For some reason however, one of my view controllers is disappearing. What I want to confirm is that UINavigationController does in fact retain its view controllers on an ongoing basis.

I've only been able to get it to crash after an extended period of time (I go to sleep, reload the app and click "Back" and the app crashes). Is there something related to the life-span of a UINavigationController or something along those lines that I need to know about? Anybody have any ideas about how to begin narrowing down the problem?

I'm assuming the easy answer is I've over-released an a view controller and it's no longer there when I click back. However I want to get some other members' opinions. Thoughts?


Solution

  • yes UINavigationController retains the UIViewController in that are in its stacks. (in fact it retains a stack of UINavigationItems that holds some data about the title, backButton, etc... and the ViewController itself)

    I guess your problem is not on the UIViewController itself, but on your memory managment.

    Don't forget for example to set your IBOutlets to nil in the viewDidUnload method, so that when your app receive a memoryWarning and releases views that are not onscreen (typically views attached to ViewControllers that are not the topmost viewController of the UINavigationController), your IBOutlets stops pointing to objets and views that don't exist anymore (probably causing the crash because your app tries then to access memory that has been deallocated since)


    PS: Note that your crashlog is not entirely symbolicated, the most interesting part (the one that correspond to your own code in your "Holler" app) is still represented as adresses to methods instead of the method names... which would have helped you a lot to know in which method of your code the crash really occurs, probably some method like viewWillAppear or viewDidLoad