UIView Delete Itself? - iphone

I have a UIView subclass called ToolbarView that sort of acts like a floating window and has a UIToolbar that has an "X" button that can make the window disappear. My question is, is it possible for the object to delete itself from within its own class?
For instance, within ToolbarView.m, I have a method closeButtonPushed which fires when the X button is pushed. Is it as simple as to remove the view from its superview, and then call dealloc? Is it even necessary to call dealloc as once it is removed from the superview there won't be any other pointers to it. Or is this bad memory practice?

Yeah, don't call dealloc ever. If the superview is the only object that has a reference to your view, removing the view will cause its retain count to go to 0, and the runtime will then deallocate the object for you.

What you have to do is in closeButtonPushed method is, call
[self removeFromSuperView];
it will remove the ToolbarView object and IOS will call the dealloc method and release objects. No need to call dealloc manually.

Related

confise when to release memory

i have created one view Controller(A) and this controller is using as a view in my app means i am adding view controllers view property to other view controller(B) view property.
in this case should i release A or their view after adding to b ........??
or relese A controller in dealloc method ???
If you are adding this view as subview of the parent view using addSubview: method and if you have some actions performed on the subview's view controller class I think it would be better to release it in dealloc. If you don't have any actions then it wont do any harm if you release it immediately. But I dont think that will be the case because if you have used view controller then it should contain some actions if not you could have chosen UIView instead. So I think releasing in dealloc is better.
If you use Viewcontroller object in interface, you can release them only in Dealloc method.If you use local variable other view controller , you can release viewcontroller object after adding to the master viewcontroller(it must be in interface).The style you use is in your hand..
This is very simple ,
See in the declaration of your property if you have retain keyword then you must call release on it otherwise NOT
The better way is reales controller A in controller B's dealloc method.
Because, if you use controller A more than one time in controller B then reduce the crash chance and alloc dealloc method multiple time.

Does UIView's removeFromSuperView method remove the UIView from memory

Does UIView's removeFromSuperView method remove the UIView from memory? I just want to be sure that the view is no longer using any memory?
UIView retains its subviews, so when you call -removeFromSuperview method then your view object is released.
So if everything else is ok with your memory management and your view is not retained by anything else then yes - your view should be deallocated and removed from memory.
Possible example when simply removing view from superview may not be sufficient to deallocate it can be view that has outlet connection and declared property for it with retain attribute - in that case it is retained by controller when it is being loaded from nib file and you may need to release that view for that case:
[iVarView removeFromSuperview];
self.iVarView = nil;
Yes. Once removeFromSuperView method is called, that view is also released from memory.
If you want to confirm with Apple's documentation, here is the link.

Objective-C: Point of releasing a View

I made a static mainmenu with a TableView. Sometimes it crashes because my Subview has allready deallocated a subview.
Is also ok to release a View in the dealloc method of the local object instead of that:
[NavController pushViewController:self.AnotherView animated:YES];
[self.AnotherView release]; //This line into (void)viewDidLoad
AnotherView is defined in the headerfile as property and also synchronozed in the .m-File
When i use the dealloc way it works great on the device, but I need to know if this is correct.
You only call release for objects you init or alloc yourself. If it is a property of your class then release in the dealloc of your class.
So in your case, unless you init anotherView a few lines above your sample code (same method), calling release on it where you are is going to cause a leak/SIG_ABORT because you have done so prematurely.
Feel free to post more code, particularly how anotherView is assigned and you may get a more specific answer.

Calling setNeedsDisplay on a UIView from another class

I have a UIView subclass that I manipulate a lot of graphics on based on touches. All the [self setNeedsDisplay] calls seem to be fine.
However, I used an instance variable pointer to my same UIView subclass instance, and then tried manipulating it and then calling [UIViewSubClass setNeedsDisplay] from another UIView class, and DrawRect is never being called. Are there restrictions to where you can call setNeedsDisplay from?
(This method is called when a button is clicked on another UIView subclass. The method is being called, but not DrawRect)
-(IBAction)loadGrid2;
{
tempSoundArray = musicGridView1.soundArray;
[musicGridView1.soundArray setButtonArrayToNull];
[musicGridView1 setNeedsDisplay];
musicGridView1.soundArray = tempSoundArray;
NSLog(#"loadGrid2 was called");
}
drawRect: will only be called when it makes sense; ie, the view must be visible, onscreen, and dirty. Is your drawRect: ever called? It should be called when the view is first brought onscreen as well.
To add to Ben:
This most likely means that you have problems elsewhere. Your pointer may not be nil or otherwise invalid or the view may not be added to the hierarchy properly.
You may want to consider not handling this type behavior within the view and instead in the view controller. Control behavior and save presentation state in the view controller and don't subclass the view classes. It will simplify your code with less "pointer passing". This will also make it easier to debug this type of problem.
If you feel your view controller is getting bloated, consider splitting the responsibilities up among multiple view controllers.

When should I release objects in -(void)viewDidUnload rather than in -dealloc?

What is the -(void)viewDidUnload is good for?
Could I not just relase everything in -dealloc? If the view did unload, wouldn't -dealloc be called anyway?
In addition to what has already been indicated, I wanted to elaborate more about logic behind -viewDidUnload.
One of the most important reasons for implementing it is that UIViewController subclasses commonly also contain owning references to various subviews in the view hierarchy. These properties could have been set through IBOutlets when loading from a nib, or programmatically inside -loadView, for instance.
The additional ownership of subviews by the UIViewController means that even when its view is removed from the view hierarchy and released to save memory, through which the subviews are also released by the view, they will not actually be deallocated because the UIViewController itself still contains its own outstanding retaining references to those objects as well. Releasing the UIViewController additional ownership of these objects ensures they will be deallocated as well to free memory.
The objects that you release here are usually recreated and set again when the UIViewController view is re-loaded, either from a Nib or through an implementation of -loadView.
Also note that the UIViewController view property is nil by the time this method is called.
As the documentation says:
It is called during low-memory conditions when the view controller needs to release its view and any objects associated with that view to free up memory.
In the same situation dealloc is not called. This method is only available in OS3 and above. Dealing with the same situation in iPhone OS 2.x was a real pain!
Update July 2015: It should be noted that viewDidUnload was deprecated in iOS 6 because "Views are no longer purged under low-memory conditions and so this method is never called." So, the modern advice is not to worry about it and use dealloc.
This is because you will typically set the #property as "(nonatomic, retain)" and as such the setter that is created for you releases the current object and then retains the argument i.e.
self.property = nil;
...does something along the lines of:
[property release];
property = [nil retain];
Therefore you are killing two birds with one stone: memory management (releasing the existing object) and assigning the pointer to nil (since sending any message to a nil pointer will return nil).
Hope that helps.
Remember that viewDidUnload is a method in the view controller, not in the view. The view's dealloc method will get called when the view unloads, but the view controller's dealloc method may not be called until later.
If you get a low memory warning and your view isn't showing, which will happen for instance about any time you use a UIImagePickerController to let the user take a picture, your view will get unloaded and will need to get reloaded after that.
Conclusion:
View Controllers have a view property. Typically a nib or piece of code adds other views to this view. This happens often inside a -viewDidLoad method, like this:
- (void)viewDidLoad {
[super viewDidLoad];
[self createManyViewsAndAddThemToSelfDotView];
}
in addition, a nib file may create a button and append it to the view controller's view.
On iPhone OS 2.2, when -didReceiveMemoryWarning was invoked from the system, you had to release something to free up memory. You could release the whole view controller's view if that made sense. Or just big memory-consuming contents in it.
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
Now, in the new OS 3.0, there is an -viewDidUnload method, which will be invoked from the system when the view has been unloaded because of low memory (please correct me: when exactly does this get called?)
-viewDidUnload is used to release all objects that were owned both by the view controller itself and the view. The reason: If a view controller holds references to childs of the view, i.e. a button, the referenced child views will not get released, because their retain count is >= 1. After they are released in -viewDidUnload, they can get freed up from memory.
Apple deprecated viewWillUnload, now you shoud use didReceiveMemoryWarning or dealloc to release your objetcs.
In iOS 6, the viewWillUnload and viewDidUnload methods of
UIViewController are now deprecated. If you were using these methods
to release data, use the didReceiveMemoryWarning method instead. You
can also use this method to release references to the view
controller’s view if it is not being used. You would need to test that
the view is not in a window before doing this.
If the view controller is popped from the navigation controller stack and is not retained anywhere else, it will be deallocated, and dealloc will be called instead of viewDidUnload. You should release the views created in loadView in dealloc, but it is not necessary to set the variables to nil, because soon after dealloc is called the variables will no longer exist.
You can release any subviews you hold on to, for example that UIImageView you retained in your loadView method, or better yet the image that was on that UIImageView.