release everything you have an #property retain #synthesize for? - iphone

I started banging away on my app and have gotten way deep and it is running great but I think I let some stuff run a little wild.
For every #property (nonatomic, retain) that then I create an #synthesize for I need to have [variable release] in the dealloc method - is this correct?
Even if it is an IBOutlet?

Yes. You declared ownership of the object by making it a retain property, which means you must relinquish ownership by releasing it.

In addition, if you have a retained IBOutlet, you should release it and set it to nil in -viewDidUnload. That lets the object release its outlets when the view is removed, particularly in response to a low memory warning. By setting the ivar to nil in that method, you avoid the risk of double-releasing the ivar if the object is subsequently deallocated.

Yes. If you retain the property you are responsible for releasing it.
Declared properties fundamentally take the place of accessor method declarations; when you synthesize a property, the compiler only creates any absent accessor methods. There is no direct interaction with the dealloc method—properties are not automatically released for you.
Declared Properties
Typically you will do this in your dealloc method.
- (void)dealloc {
[property release];
[super dealloc];
}

Related

Do I need use dealloc method with ARC?

So, I have class:
#interface Controller : NSObject
{
UILabel* fileDescription;
}
#property(strong, nonatomic) UILabel* fileDescription;
Do I need use method dealloc where property fileDescription will equal nil?
For example:
-(void)dealloc
{
fileDescription = nil;
}
If not, who will dismiss memory used by fileDescription?
Generally you don't need to provide a subclassed dealloc method as ARC manages the lifetime of the instance variables.
However it can be useful to perform clean-up other than releasing objects, for example to remove an observer or close a network connection down cleanly. You are therefore allowed to subclass dealloc under ARC, but you are not allowed to call [super dealloc] from within the subclassed method.
In your particular case it's not required, however.
No.
You don't need dealloc method in ARC.
But if you want to do some cleanup tasks when your view is dismissing or released. It's the best place, In such case you can implement it.
For example:
You are running a timer in your view and it's updating your view. When you are dismissed the view you need to stop that timer. In that condition you can use dealloc method and stop timer there.
Similar for NSNotification observer.
If you are using ARC.
No need to use dealloc and release, compiler knows that your property and objects are strong / weak so it will manage it.
EDIT:
dealloc method is required if you use coreframework objects like CG... & CF.... Even you create observers for notifications you need to remove it and dealloc is the best place to removeObserver.
Ans is NO Because with ARC no need to dealloc.
As you are using ARC you don't have to use dealloc
Complier will set the autoreleasePool depending upon the scope of the property,variable or control. And it'll will release the memory. There are different types of autoreleasepool generally we can define them as function level,class level etc etc. Hope this helps.

How to release IBOutlet defined as property?

sorry for this question, but I searched it and I didn't find an answer for that case.
I'm studying memory management for iOS and I understood, or I think so, the view lifecycle. But now I have a question on a IBOutlet (tat is linked to a UIImageView in my xib file).
I have a class like this:
#interface MyClass : UIViewController
#property (nonatomic, retain) IBOutlet UIImageView *myImage;
The question is: how can I release myImage? Is this ok?
- (void)dealloc {
self.myImage = nil;
[super dealloc];
}
- (void)viewDidUnload {
[super viewDidUnload];
self.myImage = nil;
}
Can someone explain why can't I call the release method on myView (if you had some lik it is good too!)?
Thanks in advance!
IBOutlet have nothing to deal with memory management.
But because it is retain property, so you need to release it in dealloc.
So your code is correct.
In general, you don't call release on a property, you would call it on the corresponding ivar. This is my standard way to handle IBOutlet properties:
#interface MyClass
#property (nonatomic, retain) IBOutlet UIImageView *myImageView;
#property (nonatomic, retain) IBOutlet UILabel *myLabel;
#end
#implementation MyClass
#synthesize myImageView = _myImageView;
#synthesize myLabel = _myLabel;
- (void)dealloc {
[_myImageView release];
[_myLabel release];
[super dealloc];
}
#end
What you are doing is correct, and you generally shoudnt call release on the properties, since setting to nil does that already, however if you have a backing ivar to your property you can call release on that...
There's a property and an instance variable behind the property. They both are called myImage, I presume (or you wouldn't be asking this question). You can free the instance in two ways - either release and nil the ivar, or just nil the property.
The compiler-generated setter for retained properties (like this one) works as following: release the currently held object reference (if any), assign the new value to the underlying ivar, retain it (if not nil). So when you assign nil to a property, it has the effect of releasing the current value and replacing it with nil.
To do that, use
self.myImage = nil; //invoke property setter behind the scenes
To free an ivar, use
[myImage release];
myImage = nil;
This is functionally equivalent to the code above. Marginally faster. The thing you should be clear about is the distinction between properties and backing ivars. For that very reason, some people make a point of assigning different names to them, and synthesizing like this:
#synthesize MyImage = _MyImage;
From Apple's documentation:
Legacy Patterns Prior to ARC, the rules for managing nib objects are
different from those described above. How you manage the objects
depends on the platform and on the memory model in use. Whichever
platform you develop for, you should define outlets using the
Objective-C declared properties feature.
The general form of the declaration should be:
#property (attributes) IBOutlet UserInterfaceElementClass *anOutlet;
Because the behavior of outlets depends on the platform, the actual declaration differs:
For iOS, you should use:
#property (nonatomic, retain) IBOutlet UserInterfaceElementClass *anOutlet;
For OS X, you should use:
#property (assign) IBOutlet UserInterfaceElementClass *anOutlet;
You should then either synthesize the corresponding accessor methods,
or implement them according to the declaration, and (in iOS) release
the corresponding variable in dealloc.
This pattern also works if you use the modern runtime and synthesize
the instance variables, so it remains consistent across all
situations.
First of all: consider switching to ARC if you aren't supporting iOS versions prior to 4.0.
Secondly, the best practice of writing dealloc methods says not to invoke setters. Instead, expressly release and nil your outlets:
[myImage release], myImage = nil;
Finally, when chaining together de-initialization methods like viewDidUnload, always call super's implementation after you do your own work.
The reason we nil out outlets in viewDidUnload is because sometimes views are unloaded when the system is under memory pressure. Since these outlets can be recreated easily, implementing viewDidUnload is a way to help performance, and in extreme situations, prevent your app from being forcefully terminated.
The reason we release properties in dealloc is to prevent memory leaks. So even though these two methods can look quite similar, they serve somewhat different purposes.
I don't really get what you mean by "why can't I call the release method on myView"
Your code seems correct to me but by convention I usually prefer to release the iVar directly for a retained property
I usually synthesize my property like this :
#synthesize myImage = _myImage;
And then you I release the iVar in the dealloc method
- (void)dealloc {
[_myImage release];
[super dealloc];
}
Anywhere else in the Controller I just go for the getter and setter (the dot convention)
Your viewDidUnload is correct.
By the way, if you're using ARC just declare your IBOutlet as a weak pointer. It will be automatically released in low memory situations and reloaded as soon as your view is loaded back again.
Hope this will help ;)

Memory management addSubview:

I have a UIPickerView that I allocated as an autoreleased object and use a #property (nonatomic,retain) on self to hold on to it. When I make it visible by calling [self.view addSubview:self.picker], should I call [self.picker release] afterwards? I've been doing that but the Xcode analyzer says "Incorrect decrement of the reference count of an object that is not owned at this point by the caller".
Thanks!
No. You've already autoreleased your UIPickerView. I'm assuming you're releasing the property reference in your dealloc method. That's all you have to do. The view is responsible for the subview after you've assigned it.
addSubView: retains the subview and releases it when removed (removeFromSuperview). This happens implicitly. No need to release explicitly.
how ever, if for any reason you retain picker, you will have to release it( which doesnt seem to be the case in your question).

Iphone: Where to release objects?

where i should release objects: in method dealloc or viewDidUnload?
Thanks
The correct way is to release them and set them to nil in both of those methods.
You need to release your objects in viewDidUnload since memory warnings can happen, and if your view doesn't have a superview then you should release your outlets to save memory. The framework will issue a viewDidLoad again if the view was unloaded.
You need to release your objects in dealloc, since viewDidLoad + viewDidUnload is not necessarily called.
Finally you need to set your variables to nil in both of the methods, to not be able to call release on them the second time.
A short answer for you question: dealloc()
A long and more complicated answer for your question: both
release any unused IBOutlets in viewDidUnload(). This method will be called when your device is running out of memory.
release any objects that the current view controller is responsible for memory management, and release them in dealloc(). (An autoreleased object doesn't belong to this category)
Any objects allocated and/or retained as part of loadView and/or viewDidLoad should be released in viewDidUnload. Releasing anything you alloc in viewDidLoad is easy to grasp, loadView is a bit harder if you are using a NIB. Any IBOutlet that is a property defined as retain will be implicitly retained as part of loadView.
If the view have for example a subview that is a UITextField and you connect this view to a property defined as:
#property(nonatomic, retain) IBOutlet UITextField* nameField;
Then the actual text field when loaded from the NIB will have a retain count of +2. +1 because of it's parent view, and +1 because of the property you connected it too. Thus it's memory is not freed until the view controller is released, or the NIB is loaded again.
Unfortunately viewDidUnload is not called when a view controller is deallocated. So you must explicitly release all your `IBOutlets here as well. I use this patter in order to not forget to release anything:
-(void)releaseOutlets {
// Set all outlets to nil
}
-(void)viewDidUnload {
[self releaseOutlets];
[super viewDidUnload];
}
-(void)dealloc {
[self releaseOutlets];
// Release anything else.
[super dealloc];
}
dealloc this way if the parent object is released the child objects will be released as well.

Do I need to release xib resources?

If I have something like a UILabel linked to a xib file, do I need to release it on dealloc of my view? The reason I ask is because I don't alloc it, which makes me think I don't need to release it either?
eg (in the header):
IBOutlet UILabel *lblExample;
in the implementation:
....
[lblExample setText:#"whatever"];
....
-(void)dealloc{
[lblExample release];//?????????
}
If you follow what is now considered to be best practice, you should release outlet properties, because you should have retained them in the set accessor:
#interface MyController : MySuperclass {
Control *uiElement;
}
#property (nonatomic, retain) IBOutlet Control *uiElement;
#end
#implementation MyController
#synthesize uiElement;
- (void)dealloc {
[uiElement release];
[super dealloc];
}
#end
The advantage of this approach is that it makes the memory management semantics explicit and clear, and it works consistently across all platforms for all nib files.
Note: The following comments apply only to iOS prior to 3.0. With 3.0 and later, you should instead simply nil out property values in viewDidUnload.
One consideration here, though, is when your controller might dispose of its user interface and reload it dynamically on demand (for example, if you have a view controller that loads a view from a nib file, but on request -- say under memory pressure -- releases it, with the expectation that it can be reloaded if the view is needed again). In this situation, you want to make sure that when the main view is disposed of you also relinquish ownership of any other outlets so that they too can be deallocated. For UIViewController, you can deal with this issue by overriding setView: as follows:
- (void)setView:(UIView *)newView {
if (newView == nil) {
self.uiElement = nil;
}
[super setView:aView];
}
Unfortunately this gives rise to a further issue. Because UIViewController currently implements its dealloc method using the setView: accessor method (rather than simply releasing the variable directly), self.anOutlet = nil will be called in dealloc as well as in response to a memory warning... This will lead to a crash in dealloc.
The remedy is to ensure that outlet variables are also set to nil in dealloc:
- (void)dealloc {
// release outlets and set variables to nil
[anOutlet release], anOutlet = nil;
[super dealloc];
}
I found what I was looking for in the Apple docs. In short you can set up your objects as properties that you release and retain (or just #property, #synthesize), but you don't have to for things like UILabels:
http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/chapter_3_section_4.html#//apple_ref/doc/uid/10000051i-CH4-SW18
The
[anOutlet release], anOutlet = nil;
Part is completely superfluous if you've written setView: correctly.
If you don’t release it on dealloc it will raise the memory footprint.
See more detail here with instrument ObjectAlloc graph
Related: Understanding reference counting with Cocoa / Objective C
You do alloc the label, in a sense, by creating it in IB.
What IB does, is look at your IBOutlets and how they are defined. If you have a class variable that IB is to assign a reference to some object, IB will send a retain message to that object for you.
If you are using properties, IB will make use of the property you have to set the value and not explicitly retain the value. Thus you would normally mark IBOutlet properties as retain:
#property (nonatomic, retain) UILabel *lblExample;
Thus in ether case (using properties or not) you should call release in your dealloc.
Any IBOutlet that is a subview of your Nib's main view does not need to be released, because they will be sent the autorelease message upon object creation. The only IBOutlet's you need to release in your dealloc are top level objects like controllers or other NSObject's. This is all mentioned in the Apple doc linked to above.
If you dont set the IBOutlet as a property but simply as a instance variable, you still must release it. This is because upon initWithNib, memory will be allocated for all IBOutlets. So this is one of the special cases you must release even though you haven't retained or alloc'd any memory in code.