views:

50

answers:

4

Hello,

I try to understand the memory management in ObjectiveC and still some things are a misery for me. I've got an instance variable:

    NSMutableArray *postResultsArray;

when a button is clicked in the UI I create new array:

self.postResultsArray = [NSMutableArray array];

then I add some objects to the array and when the whole operation is done I would like to release the array:

[self.postResultsArray release];

(I assume that all the objects stoed in the array will be released along with the array). The problem appears when I click the button again and in the code I want to create the array again with:

self.postResultsArray = [NSMutableArray array];

I get:

[CFArray release]: message sent to deallocated instance 0x3d9e390

Can't I initialize the same instance variable for the second time? or maybe I should not release it? and if so, why?

Thanks!

+1  A: 

You shouldn't manually release an object that is accessed through a property. Instead of

[self.postResultsArray release];

do

self.postResultsArray = nil;

and all will be fine. The setter will release the old array and then assign nil to the pointer. What is happening now is that the setter is trying to release the old array when you assign a new array to the property, but you have already released that array, hence the error.

calmh
A: 

Don't do [self.postResultsArray release];, do self.postResultsArray = nil, this has to do with the implementation of properties. They will automatically release whatever is currently stored and retain the new value.

Winder
+2  A: 

Don't to this:

[self.postResultsArray release];

When you do this, the ivar is still assigned to the old array's memory address. If you want to release the array, there are two safe ways to do it:

[postResultsArray release];
postResultsArray = nil;

Or

self.postResultsArray = nil;

What's happening is that the code for setting the postResultsArray looks like this (paraphrase, not exact):

-(void)setPostResultsArray:(NSMutableArray *)newArray {
    [array retain];
    [postResultsArray release]; // this is what's causing the the deallocation message in your log
    postResultsArray = array;
}
Giao
+1 beat me to it.
TechZen
I would add that you never release a property directly save in the dealloc method. The entire point of using properties and the `self` notation is so that you don't have to retain/release objects manually.
TechZen
I agree entirely about releasing a property directly. There are KVO issues, etc. that makes releasing a property's ivar outside of dealloc a risky proposition.
Giao
A: 

You only need to call release if you create an object with one of the "init" messages or explicitely call retain yourself. Since you do neither you don't need to call release as the code that created the array will be handling the release - most probably by using autorelease.

s1mm0t