Silly memory management issue that has me stumped - iphone

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

Related

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

When does (void)dealloc get called in an AppDelegate?

I understand that instance variables are released in dealloc (as shown below), but when exactly is it called? Are all instance variables released upon app close, or is there an accepted way for them to be deallocated individually as they become unneeded?
- (void)dealloc {
[fred release];
[wilma release];
[barney release];
[betty release];
[super dealloc];
}
Like any other object, the app delegate will be deallocated when no other object has retained it. It's pretty unusual to have an app delegate that doesn't stick around until the app terminates, and as others have pointed out, the app may not bother to release and deallocate anything just before it exits.
I think it's a safe bet that the app delegate would be deallocated if no object other than the app had retained it and you gave the application a new delegate. Aside from that unusual situation, the app delegate's -dealloc method probably doesn't get called very often at all. However, that doesn't mean that you shouldn't implement it correctly -- it's expected behavior, and things could easily change in a future iOS release.

iPhone, method returns an objective-c object with a +1 retain count

I kind of understand why I'm getting this analyzer warning. Because I'm using an object that is being passed in. I've tried autorelease and retain however these cause me other problems like unrecognized selector sent to instance.
The aim of my CommonUI function is to re-use code, but I have to cater for addSubView and presentModalViewController.
Perhaps I'm doing some obvious wrong ?
Change your code like this:
HelpViewController *helpvc = [[HelpViewController alloc] init....];
[vw addSubview:helpvc.view];
[helpcv release];
I think you don't need to pass the other VC.
There are two problems here.
First, if you call [vc release] (as the other answers suggest), you'll certainly make the analyzer happy but likely crash the app. A view controller's view doesn't retain the controller, so any button targets in the view will be pointing to garbage.
You will need to somehow keep the HelpViewController retained for as long as it is showing up onscreen. The "parent" view controller should likely retain it somehow. You could autorelease it, and return it. Then whomever calls showHelpClick... would retain the returned controller.
Second, you don't need to have the (UIViewController *)vc passed in as an argument.

release or autorelease?

should i use release or autorelease for varSecondViewController?
-(IBAction)takeNextStep: (id) sender
{
SecondViewController *varSecondViewController = [[SecondViewController alloc]
initWithNibName:#"SecondViewController" bundle:nil];
[self.navigationController pushViewController:varSecondViewController animated:YES];
[varSecondViewController release];
}
My rule of thumb:
If you're going to use it, and then no longer need a reference to it, release it,
If you're going to pass it back to the caller (i.e. return it), autorelease it.
autorelease is just a release that's delayed until some time in the future, which is guaranteed to be at least the current call stack unless a caller has created its own autorelease pool. You generally use it when you need to release an object in order to follow the memory management guidelines, but that object might still be needed further up the call stack. In this case, you're not returning the view controller and have no intention of directly holding onto it any further, so there's no need for a delay. You can just release.
In this case, release makes the most sense.

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.