Object allocate and init in Objective C

6 Solutions Collect From Internet About “Object allocate and init in Objective C”

Every object has a reference count. When it goes to 0, the object is deallocated.

Assuming the property was declared as @property (retain):

Your first example, line by line:

  1. The object is created by alloc, it has a reference count of 1.
  2. The object is handed over to self‘s setAController: method, which sends it a retain message (because the method doesn’t know where the object is coming from), incrementing its reference count to 2.
  3. The calling code no longer needs the object itself, so it calls release, decrementing the reference count to 1.

Your second example basically does steps 1 and 2 but not 3, so at the end the object’s reference count is 2.

The rule is that if you create an object, you are responsible for releasing it when you’re done with it. In your example, the code is done with tempAController after it sets the property. It is the setter method’s responsibility to call retain if it needs that object to stick around.

It’s important to remember that self.property = foo; in Objective-C is really just shorthand for [self setProperty:foo]; and that the setProperty: method is going to be retaining or copying objects as needed.

If the property was declared @property (copy), then the object would have been copied instead of retained. In the first example, the original object would be released right away; in the second example, the original object’s reference count would be 1 even though it should be 0. So you would still want to write your code the same way.

If the property was declared @property (assign), then self isn’t claiming ownership of the object, and somebody else needs to retain it. In this case, the first example would be incorrect. These sorts of properties are rare, usually only used for object delegates.

As others have noted, the two code snippets you show are not equivalent (for memory management reasons).
As to why the former is chosen over the latter:

The correct formulation of the latter would be

self.aController= [[[AController alloc] init] autorelease];

Compared with the former, this adds additional overhead through use of the autorelease pool, and in some circumstances will lead to the lifetime of the object being unnecessarily extended (until the autorelease pool is released) which will increase your application’s memory footprint.

The other “possible” implementation (depending on where the example is from) is simply:

aController = [[AController alloc] init];

However, setting an instance variable directly is strongly discouraged anywhere other than in an init or dealloc method. Elsewhere you should always use accessor methods.

This brings us then to the implementation shown in sample code:

AController *tempAController = [[AController alloc] init];
self.aController = tempAController;
[tempAController release];

This follows best practice since:

  • It avoids autorelease;
  • It makes the memory management semantics immediately clear;
  • It uses an accessor method to set the instance variable.

Note also that your desire to cut the code down to one line is why many people use Autorelease:

self.aController = [[[AController alloc] init] autorelease];

Though in theory on the iPhone autorelease is somehow more expensive (never heard a clear explanation why) and thus you may want to explicitly release right after you assign the object elsewhere.

If you’re using Xcode, it can help you detect such code with the static analyzer.
Just hit Build >> Build and Analyze

alt text

This will show you a very helpful message at such pieces of code.

alt text

One other thing to note is that your example depends on the @property definition of aController also.

If it were defined as @property (readwrite, retain) id aController; then your example works, while if it is defined as @property (readwrite, assign) id aController; then the extra call to release would cause your object to be deallocated.

You could also do

@property (nonatomic, retain)AController *aController;
...
self.aController= [[AController alloc] init];
[aController release];

with a retaining property, and it would function the same way, but its better to use the other way (for retaining properties) because it’s less confusing, that code makes it look like you assign aController and then it gets deleted from memory, when actually it doesn’t because setAController retains it.