An object selects and initializes an Objective-C object.

What is the difference between the following two methods of allocating and initializing an object?

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

and

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

Most apple examples use the first method. Why would you select init and the object, and then immediately release it?

+56
memory-management objective-c cocoa-touch cocoa
01 Oct '08 at 4:31
source share
6 answers

Each object has a reference counter. When it goes to 0, the object is freed.

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

Your first example, line by line:

  • The object is created by alloc ; it has a reference count of 1.
  • The object is passed to the self setAController: method, which sends it a retain message (because the method does not know where the object is coming from), increasing the number of references by 2.
  • The calling code no longer needs the object itself, so it calls release , reducing the number of links to 1.

In your second example, steps 1 and 2 are mostly performed, 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 are done with it. In your example, the code is executed using tempAController after it sets the property. The responsibility of the setter method is to call retain if it needs this object.

It is important to remember that self.property = foo; in Objective-C is actually just a shorthand for [self setProperty:foo]; and that the setProperty: method will save or copy objects as needed.

If the property was declared @property (copy) , then the object would be copied, not saved. In the first example, the source object will be released immediately; in the second example, the initial counter of references to objects will be equal to 1, although it should be equal to 0. Thus, you still want to write your code in the same way.

If the property was declared @property (assign) , then self does not require ownership of the object, but someone else needs to save it. In this case, the first example will be incorrect. These kinds of properties are rare, and are usually used only for object delegates.

+70
01 Oct '08 at 4:54
source share

As others noted, the two code snippets you show are not equivalent (for memory management reasons). Regarding the selection of the first of the last:

The correct wording of the latter will be

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

Compared to the first, this adds additional overhead due to the use of the pool of auto resources and in some cases will lead to the life of the object being unnecessarily extended (until the pool of autorun is released), which will increase the amount of application memory.

Another “possible” implementation (depending on where this example came from):

 aController = [[AController alloc] init]; 

However, setting an instance variable directly is strongly discouraged anywhere except in the init or dealloc method. Elsewhere, you should always use access methods.

This leads us to the implementation shown in the code example:

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

This follows best practice because:

  • It avoids auto-updating;
  • This makes the memory management semantics immediately understandable;
  • It uses an access method to set the instance variable.
+30
Oct 03 '08 at 16:37
source share

Please also note that your desire to reduce the code to one line is why many people use Autorelease:

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

Although theoretically, an abstract on iPhone is somehow more expensive (I never heard a clear explanation why), and therefore you can explicitly release it immediately after assigning the object to another place.

+5
01 Oct '08 at 7:03
source share

If you use Xcode, this can help you detect such code with a static analyzer. Just click Build -> Build and Analyze

alt text

This will show you a very useful message on such code snippets.

alt text

+5
Jan 14 '11 at 18:07
source share

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

If it was defined as @property (readwrite, retain) id aController; , then your example works, and if it is defined as @property (readwrite, assign) id aController; then an extra call to release will free your object.

+4
Oct 01 '08 at 18:38
source share

You can also do

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

with a persistent property, and it will work the same, but it’s better to use a different method (to save the properties), since it is less confusing, this code makes it look like the purpose of aController, and then it is deleted from memory, in fact, this is not because setAController saves it.

+2
Aug 04 '09 at 0:24
source share



All Articles