Memory management addSubview: - iphone

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).

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.

Silly memory management issue that has me stumped

I have a property defined as:
#property(nonatomic, retain) UITableView *settingsTableView;
Then in my viewDidLoad method I have:
self.settingsTableView = [[[UITableView alloc] initWithFrame:tableFrame style:UITableViewStyleGrouped] autorelease];
[self.view addSubview:self.settingsTableView];
[self.settingsTableView release];
Then in the dealloc method of the view controller I have:
[settingsTableView release];
When I attempt to do the release from within the dealloc I am getting a "message sent to deallocated instance". I am starting to second guess myself, anybody see anything stupid in what I've done?
Really appreciate the help on this one!
you're calling release on an object you've already autoreleased. Just get rid of the line
[self.settingsTableView release];
and you should be good.
Note that you should keep the release in the dealloc method, since the property calls retain for you, but not release.
Two things. First, you're over-releasing the table view in the first place: the autorelease call negates the need for a manual release afterwards.
Also, in general, what you release in -dealloc are things that you created in -init, -initWithCoder:, or whatever, not loadView or -viewDidLoad. In this case, the method you're looking for is -viewDidUnload; you just have to set self.settingsTableView to nil in that method, and the property setter will handle releasing it if necessary.
Here is the change you need to make.
self.settingsTableView = [[[UITableView alloc] initWithFrame:tableFrame style:UITableViewStyleGrouped] autorelease];
[self.view addSubview:self.settingsTableView];
[self.settingsTableView release];
//^^^ This line is bad no need to release this value until dealloc
//if it is defined as retain or copy
Seems obvious. You have already released with
[self.settingsTableView release];
So why release it again in the dealloc?
I believe the problem is related to your use of autorelease when you are allocating and initializing the UITableView.
You also might have a problem with releasing the settingsTableView right after you use it, vs. in the dealloc method. Anytime you alloc/init an object, you should only release it once.
If you use autorelease, the rules are a little different, so I'd recommend reading up on that again. Also, when you pass objects that you've created off to other things, they may take complete or shared ownership of the object by retaining it, meaning that you may or may not need to release it yourself anymore. The documentation for that should be on the method you're calling (like addSubView).

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

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];
}

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.