views:

217

answers:

2

First of all, i have never seen so many memory issues in my app since i started placing "self" everywhere after reading an article about how memory behaves in obj-C. Now, im getting all kinds of issues (reveals the sloppiness of my coding). Granted I am a newbie at Objective-C, i'll admit i have never had so much issues with memory management before in my life. But i reckon it takes practice to get used to this.

Now, on to my question...

I have a class interface property (self.todoCreate) that holds a reference to the above controller. This controller is navigated to by pressing a button.

@property (nonatomic, retain) TodoTaskCreateController *todoCreate;

The code below are the snippets that cause the navigation view change:

TodoTaskCreateController *viewController = [[TodoTaskCreateController alloc] 
                   initWithNibName:@"TodoTaskCreateController"
                            bundle:[NSBundle mainBundle]];

self.todoCreate = viewController;
[viewController release];
// slide-in todoCreate controller.  
if (self.navigationController != nil && self.todoCreate != nil) {
    [self.navigationController pushViewController:self.todoCreate animated:YES];
}

So here is my problem:

The first time i run this it works. Once I'm on the second view screen, I navigate back to the main view. And if i try to navigate again a 2nd time, then the app crashes, right where self.todoCreate is being assigned viewController.

Note that within the main view's viewDidAppear method, I call [self.todoCreate release].

Can anyone explain this?

PS - No wonder so many iPhone apps randomly crash.

A: 

I'm not going to speak to soon, but it APPEARS that i have resolved the crash by simply adding the viewController to the autorelease pool, and then removing all manual occurances of its release.

Now does it matter if my @property for createTodo is defined as (nonatomic, retain) as opposed to (nonatomic, assign)?

Edward An
If you do `self.todoCreate = <something>` with a `retain` property, the old value will be released; if you do the same with an `assign` property, the old value will not be released.
John Calsbeek
Wait a minute, i thought it was behave exactly the opposite from the way your described. Since retain increments the reference count, wouldnt a property described with retain be NOT released? Yet again, just when i thought i got the hang of things, something like this shakes my understanding of it. Very frustrating.
Edward An
+1  A: 

todoCreate is a property, which means when you assign a value to it, it invokes a method called setTodoCreate which looks something like:

- (void) setTodoCreate:(Foo*) newVal
{
    [todoCreate release]; // release the previous object
    todoCreate = [newVal retain]; // point to new object, and also retain it
}

Now your viewDidAppear method is releasing self.todoCreate at which point the retain count of todoCreate is 0. When you create a new TodoTaskCreateController and assign it to self.todoCreate another release is performed, but this time on an object with retain count of 0.

Instead of [self.todoCreate release], you should be using self.todoCreate = nil.

You probably shouldn't be continually destroying and creating your TodoTaskCreateController either.

Your comment regarding application crashing is most likely due to developers not testing their application to see if it handls memory warnings properly. In the simulator there is a menu option to simulate this, and your application should "survive" the warning in all of its views.

freespace