Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting an object nil versus release+realloc

This is not a garbage collected environment

I have a class instance variable which at some point in my runtime, I need to re-initialize with a different data set than it was originally constructed with.

Hypothetically speaking, what if I have an NSMutableArray or an NSMutableDictionary, would it be more efficient to do something such as:

[myArr release];
myArr  = [[NSMutableArray alloc] init....];

or just,

myArr = nil;

Will myArr release the object and leave me without a pointer to the storage in memory so I can re-use myArr?

like image 739
Coocoo4Cocoa Avatar asked Mar 09 '09 16:03

Coocoo4Cocoa


5 Answers

If you do myArr=nil; by itself, then you've lost the pointer to which you can send the release message to. There is no magic to release your object.

And, as Georg says, without being able to release your object, that memory has 'leaked'.

like image 180
Abizern Avatar answered Nov 02 '22 16:11

Abizern


You could use a property and get almost the syntax you want without the memory leak.

Use this syntax to declare the array

@property (readwrite, retain) NSMutableArray *myArray;

Then re-initialize it like this:

[self setMyArray:[NSMutableArray array]];
like image 34
Lounges Avatar answered Nov 02 '22 17:11

Lounges


If you were on Mac OS, not iPhone OS I would say that it depends on whether the garbage collector is activated or not:

  • with GC: use myArr = nil;
  • without GC: use [myArr release];

Unfortunately, on iPhone, there is no garbage collection, so if you don't want memory leaks, you have to release your object once you no longer need it.

like image 35
mouviciel Avatar answered Nov 02 '22 18:11

mouviciel


The first code block is fine. However, the second block does not leave you with an array you can use so it is not sufficient. Half correcting that block, I think you mean:

myArr = nil;
myArr = [[NSMutableArray alloc] init....];

However, this does not accomplish what you want either because you are not releasing myArr. If you have synthesized a setter for myArr, then you can get the release behavior you want from setting to nil, by using the setter (self.myArr) instead of accessing the pointer directly (myArr). Correcting your second block fully:

self.myArr = nil;
myArr = [[NSMutableArray alloc] init....];

Now we have equivalent code examples, one using setter with nil to release, the other not. They are the same.

If myArr is a mutable array as in these examples, the most efficient method is to use removeAllObjects, avoiding all the work of releasing memory only to claim it back:

[myArr removeAllObjects];
like image 4
Roger Avatar answered Nov 02 '22 16:11

Roger


One way to realize the difference might be this: Setting a reference to an object to nil does nothing to the object, it only does something to the reference.

"Releasing the object" is not "nothing", so it doesn't do that. :) In a garbage-collected language it might do that as a side-effect of dropping the reference, but in Objective C it doesn't work that way.

like image 1
unwind Avatar answered Nov 02 '22 16:11

unwind