fuzzygoat
fuzzygoat

Reputation: 26223

Use of retain in initWithCoder?

I am reading up about Encoding and Decoding and I noticed that sometimes people miss the retain off the end, I have also noticed that retain is sometimes used on some varables but not others. Can I ask ...

(1) What is the purpose of this retain and why is it sometimes not needed?

(2) Does the use of the retain imply that I need to match it with a release, and if so where?

- (id) initWithCoder: (NSCoder *) decoder {
    name  = [[decoder decodeObjectForKey: @"CardName"] retain];
    email = [[decoder decodeObjectForKey: @"CardEmail"] retain];
}

or

- (id) initWithCoder: (NSCoder *) decoder {
    name  = [decoder decodeObjectForKey: @"CardName"];
    email = [decoder decodeObjectForKey: @"CardEmail"];
}

gary

Upvotes: 10

Views: 2794

Answers (2)

Jeff Laing
Jeff Laing

Reputation: 275

You may also have been misled by people using properties as well. Its possible that you've seen people doing:

- (id) initWithCoder: (NSCoder *) decoder {
    self.name  = [decoder decodeObjectForKey: @"CardName"];
    self.email = [decoder decodeObjectForKey: @"CardEmail"];
}

which would be fine if name and email were defined as 'retain' properties. Of course, you then get into the argument about whether its legal/advisable to use property accessors in initialise/dealloc methods - some say yes, some say no, Apple seem to be on the side of no but haven't ever really given a good reason that I can see.

Upvotes: 9

user23743
user23743

Reputation:

Your first snippit represents the correct behaviour. The -decodeObjectForKey: method does not contain the word init, copy or new, so there is no promise made about whether the object returned will stay around, and if so for how long. If your object needs its ivars to stay around, it should -retain the objects it gets back from the decoder. This -retain will need to be balanced with a -release, which will be in your object's -dealloc method (so the object is created with some initial ivars which it retains, and it releases its ivars when it is destroyed). Like this:

- (void)dealloc {
  [name release];
  [email release];
  [super dealloc];
}

The retain/release dance is not needed:

  • if you're using garbage collection

  • if your object doesn't need to claim ownership of its ivars. That's not often the case; delegates usually aren't retained (but then usually aren't archived either), and properties declared with the assign modifier aren't either.

Upvotes: 12

Related Questions