Coocoo4Cocoa
Coocoo4Cocoa

Reputation: 50816

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?

Upvotes: 9

Views: 5139

Answers (6)

Abizern
Abizern

Reputation: 150575

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

Upvotes: 21

Roger
Roger

Reputation: 57

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];

Upvotes: 4

greencat
greencat

Reputation:

If what you want is to reset the contents of an NSMutableArray/NSMutableDictionary, you can also call removeAllObjects and you have a fresh array/dict to work with.

Upvotes: 1

Lounges
Lounges

Reputation: 4664

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]];

Upvotes: 6

mouviciel
mouviciel

Reputation: 67831

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.

Upvotes: 5

unwind
unwind

Reputation: 399743

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.

Upvotes: 1

Related Questions