Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iPhone: Reassignment of instance variable = deallocation?

I have an instance variable NSMutableArray* searchResults.

First, I initialize it:

self.searchResults = [[NSMutableArray alloc] init];

Then, at the course of my app, it gets reassigned frequently:

NSMutableArray* results = [searcher getResults];
self.searchResults = results;

My question is will this cause a memory leak because the array it pointed to previously may not get deallocated during this reassignment? Do I explicitly need to do this:

NSMutableArray* results = [searcher getResults];
self.searchResults = nil;
self.searchResults = results;

Of course, I release it in dealloc, and set it to nil in viewDidUnload.

like image 813
Henley Avatar asked Jun 26 '26 03:06

Henley


2 Answers

If the @property was declared with retain or copy and it was created by @synthesize, there is no memory leak. If that is not the case, you could have one, depending on the implementation of the method.

like image 145
Rudy Velthuis Avatar answered Jun 27 '26 22:06

Rudy Velthuis


Well, you may have a memory leak, but not for the reasons you think. The answer depends on how your property was declared, and whether you're releasing the object after you allocate it.

When declaring a property that your object owns (as opposed to something like a delegate, which is owned by a different object), you typically declare it like this:

@property (nonatomic, retain) NSMutableArray *searchResults;

I'm assuming this is how your property is declared. The retain clause of that declaration means that an object will automatically be retained whenever it is assigned through this property's setter method (i.e. either through self.searchResults = foo or [self setSearchResults:foo];).

If the property already references an existing object, then the retain clause causes that existing object to be automatically released when the property gets reassigned. So setting self.searchResults = nil; prior to doing another assignment does indeed cause that existing object to be released, but this really isn't necessary because self.searchResults = results; also releases any existing object before it retains and stores the new reference.

You may have a memory leak on this line:

self.searchResults = [[NSMutableArray alloc] init];

After this line, your retain count is +2. It got +1 for the alloc, and +1 for the property assignment. This creates a memory leak, unless you have [self.searchResults release] elsewhere in your method. The way I'd fix it is like this:

self.searchResults = [[[NSMutableArray alloc] init] autorelease];

Whenever you're confused about memory management, it's always worthwhile to go back and reread the Memory Management Programming Guide.

like image 28
cduhn Avatar answered Jun 27 '26 22:06

cduhn