Why is deinit not called on UITabBarController? - swift

I'm in the process of learning Swift. I wouldn't say I'm a novice, but I'm sure like many learning online I have missed a lot of fundamental steps to understanding what's really going on.
After getting pretty far with my app I am now seeing that my memory management is very poor. I am using SDWebImage caching which is definitely impacted by GIFS, but more to the point I am now learning about retain cycles and deinit.
Could someone please explain why a ViewController inside a UITabBarController deinit is never called?, why this isn't a bad thing? (unless it is) and just general advice/direction on memory management when using a tab bar controller. I have looked into retain cycles and why they are caused and fixed, but that doesn't seem to be my issue according to xCodes instrument tools.
Any advice would be much appreciated
Thanks.

A tab bar controller does not create and destroy the view controllers (tabs) it manages. It holds onto all of them so the user can switch between them as needed. Thus the view controllers from the tabs persist as long as the tab bar controller persists.
If your app's root view controller is a tab bar controller that never goes away, neither will the view controllers for the tabs.
If, instead, you create a tab bar controller and push it onto a nav stack, or present it modally, the tab bar controller will be released when it's popped/dismissed, and the view controllers will then be released as well.

Also, another reason an object may not be deinitialized is because of references. Since you are just starting Swift, I strongly suggest that you look up tutorials on Reference cycles, ARC (automatic reference counting) and memory leaks. They’ll teach you about
weak var
And the proper time to use it. When starting, I’d say it’s not too important, but they are valuable later on when trying to get a job in software development.

Related

NSViewController not released

I have a question on the ownership of windows vs view controllers and when they're released. I created a test project, and only added one line of code to the NSViewController:
deinit { print("ViewController Dismissed.") }
Why isn't this called when I close the window? I profiled it in Instruments and there aren't any memory leaks, but there is a reference to the ViewController still.
Also, I tried the "Release when closed" option on the NSWindow, still no dice. Can anyone help with understanding this? Thanks!!
I would have simply put this as a comment, but I don't have enough reputation:
Could there be a closure in your view controller that is maintaining a strong reference to your view controller or some object in your controller? That is one way a retain cycle can be created. If that was it, I would think it would show up in instruments, but it's just a thought.
Also, is your view controller part of any kind of larger navigation system, such as a tab bar controller? That could be a factor. I'm not sure.
As I know your running app always have the strong reference to a window instance, which in turn has the reference to a view controller. If you go to the Debug View Hierarchy after closing your window, you'll still see it there.If you remove storyboard entry point to that window in your storyboard, you wont have that window at all.

What is the overhead of the iPhone view controller hierarchy?

Say I'm making a game using the new storyboard feature in Xcode and I have the main menu navigation controller as my initial view controller. Then when the user starts a new game I then load the gameplay view controller using a modal segue, for example. The navigation controller would still be my root view controller while I'm doing all of my rendering etc., right?
My question is how much overhead does this take up? Does it hurt the performance of my game to just have the nav controller hanging around back there? If you've built an iPhone game, how have you handled the menus?
I am also thinking about this because I'm building in a little treasure hunt easter egg that uses the GPS. Once you get into that part of the app, you'll never go back to the game. At that point since the GPS is in use, battery life is an issue. Does it hurt anything to have the game stuff sitting back there even though it will never be used again in the current life of the app?
I've tried building a couple custom segues that actually change the root view controller to get around this, but writing custom segues is actually pretty nasty if you try to do anything that isn't simple. I'm also not sure if that's the right move.
Sorry if these are silly questions, I'm pretty new to iOS.
Here are answers on some of your questions :
The navigation controller would still be my root view controller while I'm doing all of my rendering etc., right? YES
Does it hurt the performance of my game to just have the nav controller hanging around back there? a little as memory is used but not to much according to me.
IMPORTANT NOTE : if you are using story boards your application won't work before iOS5.0 which means you will lose a lot of potential users.

Why viewDidAppear/viewWillAppear don't get called in a nested structure?

Please help, if you have any experience, our time is thicking.
I have this structure.
AppDelegate...
...Owns a _root ViewController (its view added to window)
...what owns the _main ViewController (its view added to _root's view)
...that has a Navigation controller (its view added to _main's view)
...then different viewControllers travels in this navigation stack.
But viewDidAppear/viewWillAppear methods don't get called in the innermost views. I don't know why.
As I read the documentation, it says "when added to a window". Are they works with windows? Don't think so. What should I do? Why don't these CRUTIAL methods get invoked?
Nesting view controllers is not allowed by the framework.
Yes, Apple does do it (for instance, by letting you embed one of your UIViewControllers in a tab/navigation view controller), but then they would be the ones to know how to do it.
It's still possible, by forwarding the right messages from your outer view controllers to your inner view controllers, but it takes a lot of care and is probably not very future-proof. It might save you this time, though! I.e. if you get a viewWillAppear in your _root, forward that to its sub-viewcontrollers, etc. If you manage to do this correctly for all appearances/disappearances, rotations, memory management then you're good.
Two years have passed and nesting view controllers is now supported: http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/CreatingCustomContainerViewControllers/CreatingCustomContainerViewControllers.html#//apple_ref/doc/uid/TP40007457-CH18-SW6

Understanding how app delegates and view controllers relate to each other

I'm tryin to grasp the fundamentals of Cocoa (Iphone) MVC design, but it's being quite tough. I've come accross several example applications, from the web, books.. but I've found nothing related to what I'm searching, since most of the examples just present a simple app (ie, a viewcontroller with a flipside viewcontr and a bit more..). So let's see if someone is willing to help me out in pointing me to the right direction:
My goal is to build a somewhat complex app. I'd like to have the following relation of views:
Presentation view (which would have a controller loading several memory intensive vars)
Main menu view: different options that would result in entirely new complex views. In example, a Begin option to initiate whatever the app permits to do; a second option to do another complex task with different views and actions within it, an Options option to configure options; a help option, an about option, etcetera..
In a first approach I tried to embed several rounded buttons in a view under the MainWindow nib with an associated app delegate. This approach though posed the question to how I manage to switch between views/viewcontrollers. After having uncaught exceptions because I probably don't fully understand the basics, I tried to move on to more 'simple' things.
Then I came accross the Navigation and Tabbar default Cocoa controllers. I don't want a tabbar, although it could come well for other parts of this app. Then the nav controller is what I think is most suitable for this case.
Thus, am I on the right spot if I build a hierarchichal app where its root is a nav controller? I've seen I can customize the main view to display a customized table, where each cell coud act as a button to spawn its respective view+viewcontroller. From here then I can keep building the 'leaf nodes' of this hierarchy of views/viewcontrollers, right? Eventhough I don't like the animation that by default provides the nav controller, I assume I can get rid off it..
So to sum it up in an easy way: I'd like to obtain a menu like those that can usually be seen on Cocos2d apps.
It's frustrating to ask this, I know it has to be easy but I find the documentation quite a mess aswell as the examples I've seen.. GUI programming it's being a tough learning curve :/
Thank you for any answers in advance, and excuse me for this long post.
Thus, am I on the right spot if I
build a hierarchichal app where its
root is a nav controller?
Almost. A nav controller (despite being a subclass of UIViewController) does not control views but rather other view controllers. The nav controller pushes and pops the view controllers which in turn causes the controller's respective views to load and become visible.
Therefore, the "root view" is actually the view that is controlled by the view controller that is in the nav controller topViewController property.
The app delegate serves to hold the nav controller and to tell it which view controller to push on the stack first. After that, the view controllers tell the nav controller when to push and pop them.
Otherwise, you're on the right track. You should always attempt to present information on a mobile platform in an hierarchal manner starting with the most general at the top and growing more specific as you drill down.
And you shouldn't be embarrassed at finding this confusing. 90% of the introductory/tutorial info out there, including books and Apple resources, focus on the gee whiz aspects of the interface and tell you next to nothing about the actual application design or how all the parts fit together conceptually.
You right about how little information is covered about app delegates to nav controllers. I been digging and trying to get all my screens linking etc. Having alot of fun watching my apps start to look more then just some Frankenstein monster UI. ahahah
The Itunes dev videos are great for looking at push and pop stack UIviews theory. I found they moved a little fast but after watching them the hands did make more sense. I have been forcing myself to watch them all and get a really good feel for whats going on. Hopefully have a nice app working soon.

iPhone memory consumption

I have developed an iphone application that opens to a tabbed view with the first tab being a uinavigationcontroller. Within that controller is a uiviewcontroller that contains a uitableview. There are 2 items listed in the tableview. When I select one or the other item, it displays yet another uiviewcontroller with dynamically generated uiviews.
When I press the "Back" button at the top of the navigation control, to return to the previous uiviewcontroller (that contains the tableview), and then I select 1 of the 2 items in the uitableview again, it eats up almost 2M of memory according to Instruments. This occurs each time, until it reaches about 24M, and my application crashes.
I am registering no leaks whatsoever.
Is there something I need to be doing when the "Back" button is pressed to release the memory allocated to the uiviewcontroller.
I'm not sure how far you are in iPhone development, or how much you know about the memory management, but it could be a reference counting issue. Remember: If you call alloc or retain, you need to call release, and never call release on something you haven't alloc'd or retained.
The navigation controller retains all view controllers pushed onto its stack, so if you ensure that such view controllers are autoreleased or that you otherwise have no claim on them (e.g., alloc, push, release), they will automatically be released when popped.
If you're doing this and you're still losing memory, perhaps you are over-retaining the your custom views from their view controllers?
It's difficult to say without seeing code, but one thing that might be useful is implementing -didReceiveMemoryWarning on all your UIViewControllers and logging details of them -- then if you see a memory warning from a view controller you think should have been deallocated, you have a starting point for further investigation.
Also, have you tried the Clang Static Analyzer? The Leaks tool is useful, but gives plenty of false negatives. The CSA is no panacea either, but it catches some things Leaks misses.