iPhone Dev - Where to put lazy loading code - iphone

I already had a question like this, but I already deleted it anyway.
I have very simple app that has a root view controller and it switches between two other view controller views. So in my root view controller, It lazy loads the instances of the two other view controllers. Each time the switch button in the toolbar is pressed, the current view controller being displayed (its view) is unloaded (set to nil), and the new one is loaded and added to the subview.
Since I load my view controllers and unload at specific times, the lazy loading code being in the getters is very confusing because I don't actually want to load them right when I use them, I need to load them before so the flip animation will look good. So I think I want to make loadFirstVC and loadSecondVC methods to load the view controllers. Is this a good idea?

The main reason for lazy-loading is NOT to defer loading that will definitely occur. It is for deferring loading that may never be needed. (It's also good for forcing reloads when the data has changed, but that's not your issue here.)
Example: Let's say you have a bunch of data about a person, including a photo, which is stored in an external file. But the photo will only be displayed if the user goes to a subview, so why load the photo from its file until you know for sure that the subview is going to appear? Boom, use lazy loading.
By the time you KNOW you want to load a certain piece of data, it's unlikely to matter very much when exactly you load it.
When does it matter? Well, that's really a matter of optimization. There's a saying you may have run across; if you haven't, this is as good a time as any: "Premature optimization is the root of all (programming) evil."
So ask yourself two questions:
Will the piece of data definitely be needed? If NO, proceed with the lazy-loading technique. If YES, go to question 2.
Does it MATTER when I load the data? [An example would be, it's huge and I don't want to load it until I've UNLOADED something else to make room for it] If NO, put it any place that works. If YES... Come back and ask us again, and provide more details.
...I suspect this doesn't answer your original question, but it sounds like you may be asking the wrong question in the first place. Apologies if I'm mistaken.

Related

How can I optimize my controllers so they load faster?

Most of the iOS apps I use are very responsive, when I tap on an element it goes to the next view right away. In my app, some of my view controllers take 0.5-1.0 second to load.
My code is all in the viewDidLoad method and I'm pretty sure that's the problem but I can't move anything out since I need every single element that I instantiate.
A solution I thought is to move all the work I do in viewDidLoad in a thread then call the main thread when I'm ready to call addSubview, would that work even if UIKit is not thread safe? Or is there something else I'm missing?
Try to move some code you might have in viewDidLoad to viewdidAppear. viewDidAppear is being called once the view is presented. If you have to make some hard work, do it there and maybe show aa spinner somewhere while you do that.
What are you exactly doing in viewDidLoad? Btw remember that a view is only loaded when you need it, if you want to switch between views faster I can suggest you to create an initializion phase where you call -view on all the view controller you want to show, maybe helped with a spinner or a progress bar. but pay attention this would work only with intensive loading task and not memory consuming tasks. It sounds very strange your request, so is better the you try to explain better why your viewDidLoad is so slow, maybe there is something wrong.
Define your UI elements in Xcode as part of designing the interface. That way, Xcode can compile your storeyboard or xib files into the rapidly loading binary form.

iOS Logout design

I have an app that has many web services and notifications going on. I need a logout feature. I wish there was a way simply to kill the app and restart it but there is not. Does anyone have some recommended guidelines on creating a logout function (it will take the user back to the login screen). The problem is there are notifs that should be unsubscribed from, views that should be removed, view controllers that I want to be released, then everything to reinitialize. That seems like a lot of work for a simple task. Any thoughts?
The first thing to make sure when terminating all requests is to change all delegates that are supposed to receive responses to nil. After you've taken care of this, you should indeed remove all irrelevant view controller's views from your root view (and release them if they are retained anywhere), and of course flush any existing data you don't need. If you design your MVC elegantly, you can achieve these actions without a lot of fuss, for example a ScreenManager Singleton class that manages all your view controllers should have no problem taking you back to the login screen while releasing any other view. A DataManager Singleton class that holds various data collections should have no problem removing any unneeded data entities and so on...

Save from viewController?

I have a very small bit of data that I would like to archive from my apps view. My question is, its far easier to save this data from the viewController, but should I really be pushing it back into my model and saving it there? BTW: I also need to do a quick load of this data when the app starts up.
Interesting question. If the data is not part of the model, then, no, the model classes should not take on the responsibility of saving it. If the data is only concerned with the view, then perhaps the view object should be responsible for saving, but that would break the rule that view objects should only concern themselves with display.
Seeing as we are in Cocoa territory, I think this task falls firmly to the ViewController. If you make sure that the ViewController is represented by an object (blue box, if I'm not mistaken) in Interface Builder, then you can take advantage of awakeFromNib to load your save data. BTW, it sounds like NSUserDefaults should be mechanism to use to do the archiving/saving & unarchiving/loading.

UITableViewController.view crash

So I'm trying to use a UITableViewController (let's call it homeView) in my iPhone application to display a simple table with only a few rows of text which are loaded from an NSArray in the controller. I want to display the table in the grouped style in a subview of a subview (let's call it subSubView) of my main controller. When I try the following: [subSubView addSubview:homeView.view], my app crashes on launch. However, when I allocate the object without adding it to any views, it launches fine.
What's the best way (or rather a working way) to display the table generated by my UITableViewController?
There isn't enough to tell for sure what is going on, but if I had to guess I would think that you probably aren't retaining homeView. Normally I would say that as a comment to your question, since it is not really an answer, but I have a completely separate answer:
Just use a UITableView, not a UITableViewController. Instead of trying to embed a controller within a controller (which is quite difficult since Apple doesn't expose the necessary tools to actually modify the view controller hierarchy), just make the VC you are writing support the appropriate delegate/dataSource methods and directly create the view.
While it might make some logical sense to try to embed VCs inside of each other, with the exception of the builtin container VCs (UINavigationController, UITabBarController) it Really Doesn't Work™. The technical reason for this is that internally some of the event routing and messaging depends on parentViewController being correct, but since you can't set it (setParentViewController: is private) tons of latent bugs in UIKit start rearing their head. The internal collection classes can set the parentViewController correctly, so everything works right.
Also, one last thing. In your question you named your view controller homeView. Please, please on't do that. A view controller and a view are separate things, call it homeViewController. Aside from the fact that a lot of new iPhone developers get confused about what the distinction is, there is nothing more aggravating then tracing through someone else's code and realizing that something you are assuming is one type is another.

How to deal with low memory warnings on the iPhone?

I'm having problems with my application receiving low memory warnings while the user is deep within a navigation controller stack of views. After the user browses through a bunch of hierarchical options in subsequent UITableViews, he can open a PDF document in a UIWebView (in a different view controller).
Everything works fine, the PDF loads and the user can flip through the pages. However, when the document is a bit large, or has several pages, and the user taps on the "Back" button in the navigation controller, he app crashes as the previous view controller in the navigation controller stack has been deallocated.
After searching around for ways to deal with low memory warnings, and dealing with this type of problem, I found several posts that just advise people to release the objects that can be released, and then lazy-load them later on when the user tries to load a view that has been deallocated. One of these posts is Craig Hockenberry's Dealing with memory loss: the cleanup post.
While that's a bit helpful, it doesn't give me much information to work from.
Can someone provide a simple guide on how to deal with low memory warnings, and how to implement "lazy loading" of objects?
When memory is low, the system sends out a series of memory-related messages. Any instantiated view controllers will get the -didReceiveMemoryWarning message. If you don't implement this, the default action (assuming the view controller is not front-most) is to release the controller's view member. If you've got hooks into it, or perhaps into its subviews, that could cause issues when your controller gets returned to the top of the stack.
Your first task is to figure out what exactly is causing the problem. Which object is being deallocated? Usually, fixing this is simply a matter of making sure the object is retained properly.
I suggest you use NSZombiesEnabled to try and track down the object you're having trouble with. Once you have that, you can make sure you're retaining it properly.