Objective-C: allocation and deallocation

xcode While reading the book by Mr. Kochan (1st ed): "Programming in Objective C" , I noticed that he uses the following code (you can see it at pages 342-344) to explain that the initWithString is preferable to stringWithString because the AddressCard class would own the name variable contents. Also, I don’t get any errors making repeated calls to the setName version with the stringWithString method.


//I didn't added here the header file which has the needed declarations
#import "AddressCard.h"
@implementation AddressCard;
-(NSString *) name{    
return name;

//Recommended code:    
-(void) setName: (NSString *) theName{     
[name release]     
name = [[NSString alloc] initWthString: theName];     

//Incorrect code according to Kochan:    
-(void) setName: (NSString *) theName{     
[name release]     
name = [NSString stringWthString: theName];     

//I skipped the rest of class implementation  

The problem was that I didn’t quite well understand why is better to use the stringWithString method since any local variable assigned that way would have it’s memory "owned" by NSString instead of the local class.

But the fact is that I misunderstood it. After more reading, the rules are quite crisp and easy to understand :

  • all objects which are returned by an alloc, copy, copyWithZone, or new call have a retain count of 1.
  • any retain increases the receiving object’s retain count.
  • any release decreases the receiving object’s retain count.
  • the autorelease tells the current autorelease pool to send the receiving object the release message “later”.
  • As a general rule, any factory method that doesn’t have “new” or “copy” in the name (e.g., stringWithString:) returns an object that it has autoreleased on your behalf.

In English words for newbies to Objective-C as I am:

  • Any method whose name contains copy, alloc, retain, or new returns an object that you own.
  • Any method that doesn’t, returns an object that you don’t own.
  • To own an object, retain it.

The incorrect part of the implementation of setName: that I showed before is the fact that it stores an autoreleased object in an instance variable, while I mean to own the object. Either I should retain it or, in this case, copy it.

The simpler case is to use alloc and initWithString:, as in the correct example; the other way would be copy.