(iphone) uiimage, view, subviews memory management - iphone

I need to release uiimage/view/subviews when I want, and have a few questions regarding proper practice of releasing them.
[imageView removeFromSuperview] would release the imageView and imageView.image?
view = nil; would release its subviews/and associated uiimages recursively? if not, should I implement a recursive function to release a view's subviews?
Thank you
Edit.
I looked at UIView's library reference
addSubview --
This method retains view and sets its
next responder to the receiver, which
is its new superview.
removeFromSuperview --
If the receiver’s superview is not
nil, the superview releases the
receiver. If you plan to reuse a view,
be sure to retain it before calling
this method and release it again later
as appropriate.
still not sure [imageView release] releases uiImage associated with it,
and would I still need recursive releasing of subviews. ie a view's getting dealloced would automatically guarantee it's subviews release?

[imageView removeFromSuperview] would
release the imageView and
imageView.image?
removeSuperView calls release on the view, but you should pay attention to the views retain count. Just because you called removeFromSuperview doesn't mean it's doing what you want.
view = nil; would release its
subviews/and associated uiimages
recursively? if not, should I
implement a recursive function to
release a view's subviews?
No, you probably want to do (depending on how you've managed your subviews during their creation. If the superview was their only reference, they likely have a retain count of 1 and therefore calling release after calling removeFromSuperview will result in an error):
for (UIView* subview in view){
[subview removeFromSuperView];
[subview release]
}
[view release];
EDIT: To answer your final question, no, calling release on a view does not automatically call release on all of its subviews. You have to do it yourself, whether with release or with removeFromSuperview.

When you do [imageView removeFromSuperview], it won't release anything. You need to so [imageView release] afterward. Even so, you still need to put your memory releasing for that view in imageView's dealloc.

Related

How to release subviews

In my iPhone/iPad app,
I am adding one subview to my main view.
This subview has one imageview and button.
When to release them ?
My code is here,
customAlertView=[[UIView alloc] initWithFrame:CGRectMake(0, 0, 600, 600)];
UIImageView *imgv=[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"celebration.png"]];
UIButton *btnOK=[UIButton buttonWithType:UIButtonTypeCustom];
[btnOK setTitle:#"OK" forState:UIControlStateNormal];
[btnOK addTarget:self action:#selector(alertOKClicked) forControlEvents:UIControlEventTouchUpInside];
[customAlertView addSubview:btnOK];
[customAlertView addSubview:imgv];
[self.view addSubview:customAlertView];
[imgv release];
[btnOK release];
In one another method I am writing the code.
[customAlertView removeFromSuperview];
My confusion is imageview and button is there If
I release the customalertview here will it releases its subviews automatically.
If yes then no problem.
If NO how to release it
as I have done here released the objects immediately after adding subviews.
It will cause my OK button Unworthy. And will not affect the button click.
So, On removing from superview should I write.
[[customalertview subviews] release];
Your code is correct.
You release them after you've added them to the alert view, as the alert view takes care of retaining them. When you call removeFromSuperview, it'll get released automatically.
I think the points you are missing, based on your comments on the existing answers, are the following:
A view retains its subviews - so if you create a new view object, and add it as a subview to something else, you can then safely release it, unless you'd like to keep a reference around for it yourself.
When a view is removed from its superview, it is released. So if there are no more objects retaining it, it will be deallocated.
When a view is deallocated, it will automatically release all of its subviews, and so on down the tree.
Enable ARC as soon as you are able to.
You are doing it the right way. The customalertview will releases its subviews automatically.
Your object will be released when the release count go to 0, that means in the theory, and if you are coding well, that this object does not have any reference to it anymore.
While you maintain your custom alertView in your view, you have an object retaining your things, so the release count will not be 0 until you remove the customAlertView, because you have added they to the customAlertView, and when you remove the alert, the alert will be released, and all the things that it is retaining will be released too.
Hope it help you to understand how things work.
If you want to know more about memory management you can take a look at apple documentation here
EDIT:
I forgot to mention that you will need to release your custom alert too after you remove it.
If you do not understand the memory management you also can take a look at: http://cocoadevcentral.com/d/learn_objectivec/ section 7

UIViewControllers... Memory Management With SubViews

I have UIViewController who has several subviews but tracking each and every subview allocated is difficult task as the actually coder is not me and need to handle the memory consumption.
My question is there a way to control the memory calling a recursive function to remove and release all the subViews in the UIViewController without knowing the actual reference name ?
As in the code below :
for (UIView* subview in view){
[subview removeFromSuperView];
[subview release] ;
subview = nil;
}
When you call removeFromSuperview on a view it will automatically decrement the retain count (because the superview no longer requires a reference to the view you've just removed).
If you have added your views to the superview in a standard manner there shouldn't be any need to do what you're doing - either you've added your views and then released them, or your views are properties and the release happens later.
The code you're proposing (the recursive loop on all subviews) is a bad idea, because you don't actually know whether your subview is safe to be released or not. You could easily trigger a bad access.

is removeFromSuperview releases the object?

I am using removeFromSuperview for removing a view from its superview. I am also using release after removeFromSuperview on that object, sometimes its work fine but sometimes give bad access.
is removeFromSuperview also call release to the object ?
Yes, removeFromSuperview also releases view.
You need to release your view after you have added it to its superview.
CGRect frame; // let's assume you already have defined frame and superview
UIView *superview;
UIView *subview = [[UIView alloc] initWithFrame:frame];
[superview addSubview:subview];
[subview release];
Or just use autorelease, when you create a view.
UIView *subview = [[[UIView alloc] initWithFrame:frame] autorelease];
[superview addSubview:subview];
In both cases, you don't need to call release after you call removeFromSuperview.
Yes, addSubview calls retain, and removeFromSuperview calls release. So your call to release does not belong there (it probably belongs after you assign the subview, assuming you do not want to hold the object).
The correct answer is "probably". This is an implementation detail that you shouldn't even really be thinking about. If your code needs to work with the subview, then you should be retaining it before you start working on it, and you should be releasing it when you're finished working with it (which may or may not coincide with removing it from it's superview).
I imagine testing would show that removeFromSuperview does release the view, but you cannot depend on this behaviour and should never assume it will happen. Even if it does always happen now it might not in future.
You shouldn't even need to think about memory management at such a low level as this. If you retain the object with retain or copy or alloc or new then you are responsible for counter-acting that with a release at some point in the future.
If you did not do any of these things, then you should not be releasing it. The methods for adding a subview to a view do not contain retain or copy in their name and therefore you are not supposed to release it yourself when you remove it from it's superview.
The view system is very complicated, especially on an iPhone with such a limited amount of RAM and not inadequate storage to use virtual memory. Stick to the rules and you should be fine. Or enable ARC.
Actually removeFromSuperview decreases the retainCount property of the view Object and so as the release.
So,if you do the way Aleksejs said.
UIView *subview = [[UIView alloc] initWithFrame:frame];
[superview addSubview:subview];
[subview release];
subview -> alloc= retainCount = +1 ,
subview -> addSubView = retainCount = +1
subview -> release = retainCount = -1.
subview -> removeFromSuperView = retainCount = -1
(subview removed from memory)

view will disappear is not firing

i am using addSubView method to add views. Did any alternative methods are there for viewWillDisappear? viewWillDisappear is not firing. I want to release all allocated objects when the current view get dissapear. Currently i am using dealloc method to do this. But dealloc method is firing not quickly. Since i am getting memory warings and sometimes the my app may crash itself. The main problem is with voice files.
addSubview/removeFromSuperview (these methods relate with views not view controllers) doesnt call viewWillAppear/viewWillDisappear methods. You should write release object code in dealloc() itself.
removeFromSuperview should call dealloc().
You can try to release objects in method viewDidDisappear. Then you won't wait for firing method dealloc.
Also in method viewDidDisappear you can try to remove all subviews from superview (that will call viewWillDisappear to all subviews):
NSArray *subviews = [self.view subviews];
for (UIView *view in subviews)
[view removeFromSuperview];
release objects in viewDidUnload/viewDidDisappear and set to nil in dealloc
this might work, but you should surely look why viewWillDisappear is not called.

Release for controllers and views

If I have a set of custom UIViewControllers that I release in a high level application "restart" routine, would a good way to release their views be to set
self.view = nil;
in the dealloc method?
I'm not sure where your views are, but you usually would want to remove them from superview (if they have one)
[someView removeFromSuperview];
if it's retained by something else other than its superview, you'd want to release it
[someView release];
assuming your retainCount is then 0, dealloc will be called (in 99% of the cases, you should never call dealloc yourself)
then yes, you would want to nil it.
someView = nil;
then you can recreate your views or whatever you want to do.