2
votes

I'm a objective c newbie, and i'm having a bit of problems with memory management, I've read the apple's memory management policies, however i need a bit of clarification here, this is pretty simple i guess, but i would like to ask you if I'm right:

Given this property:

@interface Test : NSObject {
  NSArray *property1;
}
@property (nonatomic,retain) NSArray* property1;
@end

...

//And its implementation:
@implementation Test
@synthetize property1;
-(id) init {
  if (self=[super init]) {
    self.property1=[[[NSArray alloc] initWithCapacity:5] autorelease];
  }
  return self;
}
-(void) dealloc {
  [super dealloc];
  [property1 release];
}

@end

Is it right to issue an Autorelease message to the allocated object in the init method?, i do this cause in apple's document, says that every allocated object should be released by the developer, then, I think, alloc sets retain count to 1, then the property (nonatomic, retain) adds 1, so retain==2, then autorelease substracts 1, and when the dealloc method is called, property1 is released and retain count==0, am I right?

3
FYI: [super dealloc] has to be be the last thing in your dealloc method. Doing anything after you call [super dealloc] is a bug.Chuck
You can simplify your NSArray creation by doing: [NSArray arrayWithCapacity:5]. That is identical to what you have above.Dave DeLong
Also realize that you're creating an immutable array with a capacity of 5, and you won't be able to modify the contents after creation without replacing the array. You can also call [NSMutableArray arrayWithCapacity:], but you'll want to make the property type match if the array should be mutable.Quinn Taylor

3 Answers

6
votes

You have your memory management right, though Apple (and a lot of other people) generally recommend not using accessors in your initialization methods because accessors can have side effects beyond simply setting an instance variable that your class might not be set up to handle yet. And in that case, you wouldn't want to autorelease since you'd want ownership of the object.

2
votes

one side note: in your dealloc, you need to release the property before calling [super dealloc], because [super dealloc] eventually deallocates the memory of the object, which includes the memory containing the property1 variable, so it is invalid to refer to that variable after you call [super dealloc]. It should be:

-(void) dealloc {
 [property1 release];
 [super dealloc];
}
0
votes

One of the nice things about using properties is that you can encapsulate all of your "releasing" behavior regardless of whether your property is set to retain, copy, assign, or whatever by just doing this:

self.property1 = nil;

Personally I've gotten in the habit of setting all properties to nil (using self.property, not just accessing the member variable directly) in dealloc so that even if I change how the memory management works for the member variable it works correctly.