some custom UIView lost after my iPad app received memory warning - iphone

I'm developing an app to browse online photos, and sometimes received memory warning(level 1), after that, if I go back to last UIViewController(in a NavigationControll), I found that some custom UIView lost, I cannot get them back, but I can create new such UIView
does anyone know the problem?

The memory warning prompts the os to dump any unneeded views. If you create them in IB, or in the viewDidLoad or loadView method in your view controller they'll be re-created when your view re-loads. You could also have your view controller retain them specifically, but that'll have a larger memory footprint than just re-creating them whenever they're needed.
I should say, loadView is only called if you don't use a nib for creating your view, so viewDidLoad is probably where you want to put them.

It's expected behavior. You can override didReceiveMemoryWarning (i.e. do nothing and don't call on super); but what you really want is to handle those situations correctly, i.e. set the views up again if necessary.

Related

Timing for add Notification observer in UIViewController subclass

I'm fairly new to Cocoa Touch. Right now I'm trying to subclass UIViewController to provide my custom view. Since I intend to save the content of a UITextField (passcodeField) using NSUserDefaults, I want to be notified whenever the UITextField changes its value.
I've read somewhere that in order to do that I should add the view controller to be an observer of the UITextFieldTextDidChangeNotification notification. However I'm just not sure when to do that. I've considered several options.
In the -loadView method. However, since I'm loading my view using a XIB, I think i shouldn't mess with this method and should instead leave it as-is. (Am I correct on this point, BTW? )
In the -viewWillAppear method. But this method may be called multiple times because the view may be moved out and into the screen without being destroyed and recreated. (Am I correct? ) This will not do any harm to the program but sure doesn't seem like the correct way.
In the initializer of the UIViewController. If I want to add the notification there I must reference the UITextField. By doing this I essentially cause the view to created before it is really needed. Also I think I read somewhere that if the system runs low on memory the offscreen views may be destroyed. Thus I may lose the notification observing if such thing happens, right?
So I'm totally confused right now. Could you guys give me some advice of where to put it? Thanks so much!
Put it in the - (void)viewDidLoad method of your ViewController remember to call [super viewDidLoad]; at the start of your implementation.

awakeFromNib called more than once

This is driving me crazy.
I am under the impression that awakeFromNib Method is called only once(even when that view is visited again), correct me if i am wrong.
I have an app with 3 views.
The last one being the subclass of a UIview where i draw using drawRect.
I had a working code with the method awakeFromNib in the last view, with the method being called only once how many ever times i visit the view.
Now i deploy the app to my device and update my Xcode to version 4.
When i run the code again and debug, the method awakeFromNib is called everytime the view is visited.
I dont think update would do such a crazy thing, but i am thoroughly confused.
Is there some kind of a memory leak or am i missing something?
Thank you
I am under the impression that awakeFromNib Method is called only once(even when that view is visited again), correct me if i am wrong.
-awakeFromNib will be called on each instance of a class whenever an instance of that class is loaded from a nib file. You should be able to expect it to only be called once on a particular instance but should handle it being called many times on different instances of any given class.
UIViewControllers will unload their views when they receive a memory warning and their view is not visible. The view will be reloaded the next time the view controller's 'view' property is called. You should understand and support this behavior to minimize your app's memory use as it allows you to only keep the currently visible views in memory at any given time.
It sounds like you are not expecting that controller's view to be unloaded and reloaded from your nib.

How to recreate views released when memory warning is received

If an application receives a low memory warning and a view controller releases the view, how does one reload the view the next time it's needed. I have my views defined in a .xib file and on earlier iphones, the views are being set to nil. Where/when/how do I recreate these views if they are removed?
I was writing my code pretty much horribly wrong. I was setting views to nil in viewDidUnload but all my creation was done in init. So when the application received a memory warning, when I went back to that view controller, the views were gone. This answer helped me realize my mistake; namely, that additional views could be added to viewDidLoad so that if they are released due to memory warnings in viewDidUnload, they can be recreated.

application: didFinishLaunchingWithOptions doesn't execute, but RootViewController: viewDidLoad does, how is this possible?

I'm playing around with the iPad SplitView template and it was working fine before I started swapping out view objects in my RootViewController. When it was working fine, the application:didFinishLaunchingWithOptions method would be called and would setup my persistant store objects, then the RootViewController:viewDidLoad method would be called to populate my rootView with data from my store. I opened up IB and started swapping out view objects in my RootView and now the application:didFinishLaunchingWithOptions method never gets called, but the RootViewController:viewDidLoad method still does. Obviously, the app crashes because the viewDidLoad method depends on the successful execution of the didFinishLauchingWIthOptions method to setup the persistent store objects. Does anyone have any thoughts on what is causing this or how I can go about investigating what's causing this?
I'm obviously new to iPhone OS development, so I apologize if this questions is absurd in any way. Thanks so much in advance for your help!
This is propabaly caused by the fact that in MainWindow.xib, your application delegate object is not connected to File's Owner (UIApplication). You can open the MainWindow.xib and right click on your App Delegate to see if it has a connection in Referencing Outlet to File's Owner. If not, set it to. And this will fix your problem.
-viewDidLoad is not called from -application:didFinishLaunchingWithOptions:. They are independent. The call hierarchy could be summarized as:
load app; call -application:didFinishLaunchingWithOptions:
window is visible, load views of view controllers.
call -viewDidLoad.

is applicationDidFinishLaunching the wrong place for setting an image for an UIImageView?

I found out this:
applicationDidFinishLaunching (an delegate method of the UIApplicationDelegate Protocol) seems to be called BEFORE my views from the nib file are loaded completely. So I tried all the day to change an image of an UIImageView right after my app launched in the iPhone simulator, but nothing happened.
Then I wrote a little action method that I call with the press of a button. And then it happened: WORKS!
So the applicationDidFinishLaunching delegate method isn't really the right place for stuff that has to be done after the app is really "ready". I gues there's something better that waits for the nib to be loaded completely. but where? and what?
I gues there's something better that waits for the nib to be loaded completely. but where? and what?
For application specific things like global settings, preferences, etc., -appDidFinishLaunching is the right place.
For UIView specific things, you typically use the -viewDidLoad method in a UIVIewController subclass. It is pretty much the only place you are guaranteed that the nib file is loaded, the IBOutlets are initialized and the IBActions are attached.
This is difference from the Mac OS X world, where -awakeFromNib was the place to do it.
Hey until your views and their view controllers instantiated you can't modify their ui. However just for the sake of your problem you can always declare the uiimageview as a property of your app delegate class and initialize it in the appDidFinishLaunching event. But that's the worst practise. As on the iPhone which has limited memory always lazy load ie: only initialize objects when and just before they are actually required by your UI. So ideally you should be doing this in the viewDidLoad event of the view where you want to use this UIImageView.
applicationDidFinishLaunching is usually used for stuff like database file checks, opening database connection, populating global variables, any other application wide logic, checking for an available Internet connection etc