views:

223

answers:

2

I need help with deallocation of my NSMutableArray of custom objects. I need to retain the array and so I have added a property in .h and I release it in dealloc in .m file. When I add objects to the array, I do the following:

  myarray = [[NSMutableArray alloc] init];
  [myarray addObject:[[mycustomObject alloc]initWithObject:obj1]];
  [myarray addObject:[[mycustomObject alloc]initWithObject:obj2]];

Now, I don't know how to release mycustomobject. If I do the following:

   [myarray addObject:[[[mycustomObject alloc]initWithObject:obj1] autorelease]];

I run in to problems when I access the array later. Please advice.

+4  A: 

I don't think you understand how memory management in Cocoa works. The array will retain the objects you add to it, and it will release them by itself when the array no longer needs them (such as when you release the array).

In other words, add the autoreleased object to the array, and don't worry about its retain count after that. If you want to remove it from the array simply remove it (using removeObjectAtIndex: or something similiar). If you think you want to release the object without removing it from the array then you are doing something wrong, since that may leave a dangling pointer in your array that will cause you to crash later.

You should really really go over the documentation again, particularly the section on Object Ownership and Disposal.

Louis Gerbarg
+3  A: 

The proper way to do this is to let the array maintain ownership of the custom object:

NSMutableArray * array = [[NSMutabelArray alloc] init];

for (id obj in anArrayOfObjects) {
  mycustomObject * customObj = [[mycustomObject alloc] initWithObject:obj];
  [array addObject:customObj];
  [customObj release];
}

If you're having difficulties accessing your array later, then you're doing something wrong with the memory management of the array.

Dave DeLong
ok, this is embarassing. [myarray addObject:[[[mycustomObject alloc]initWithObject:obj1] autorelease]; actually worked as expected. I remember seeing issues with it in the beggining, might have been a different glitch. Thanks all for reaffirming!
Dave
@Dave Your answer is certainly correct, but his approach (using autorelease) is also correct, and shorter. I understand the intent behind avoiding autorelease, but it's so darn fast and with so little overhead that shorter is generally a much easier way to go. Particularly when the objects in the array will be around for a while, and we're not just creating a lot of transient temporary objects. Even so, a correct and helpful answer deserves an upvote... ;-)
Quinn Taylor
@Quinn @Dave - yes, wrapping it in `autorelease` works just fine (because you're relinquishing ownership) and is perfectly acceptable. It's my personal preference to avoid deep nesting of method calls. IMO, splitting it up onto different lines makes it much more readable and clear.
Dave DeLong
(NOTE: I told Dave over IM that double-clicking on a bracket in most decent editors, including Xcode and BBEdit, highlights all the code between the brackets. with deeply-nested method calls, this is a great way to visually parse what you're looking at. The autorelease is my preference, because all the memory management is in one place, rather than a floating release waiting to be accidentally pruned. I've done it to myself before.)
Quinn Taylor
When dealing w/ custom objects (ie something more complex than an `[NSNumber numberWithInt:i]` or whatever), I like to split things up onto different lines because I usually also have to do other customization to the object before adding it to the array. Again, it's just a style choice, and this is my style. :)
Dave DeLong