huggie
huggie

Reputation: 18237

Who is responsible for releasing objects in an array when copying?

In Objective-C, if array1 is copied onto array2 using mutableCopy, and suppose the code is done in main(), who is responsible for releasing the objects contained in the array? Is it main() or array2?

Upvotes: 3

Views: 475

Answers (4)

John Calsbeek
John Calsbeek

Reputation: 36497

The ownership responsibilities are not changed by storing objects in an array. Here's an example:

int main(int argc, char *argv[])
{
    // ...

    NSObject *obj1 = [[NSObject alloc] init]; // owned
    NSObject *obj2 = [[NSObject alloc] init]; // owned
    NSObject *obj3 = [[[NSObject alloc] init] autorelease]; // not owned

    NSMutableArray *array1 = [NSMutableArray arrayWithObjects: obj1, obj2, obj3, nil]; // not owned
    NSMutableArray *array2 = [array1 mutableCopy]; // owned

    // ...

    [array2 release];
    [obj2 release];
    [obj1 release];

    // ...
}

This code directly allocates obj1 and obj2, so it owns them and must release them, but it autoreleases obj3, so it doesn't have to release that. In the same way, it doesn't own the result of arrayWithObjects:, so it doesn't release that, but it does own the result of mutableCopy, so it must release that. The objects being stored in an array is irrelevant—all you need to care about is ownership.

Both arrays keep strong references to their content, so obj1, obj2, and obj3 won't be deallocated as long as the arrays exist—but that's a detail of the NSArray contract, it doesn't affect how you manage the ownership of the objects or the arrays.

These are all details of Cocoa's memory management conventions, not arrays.

Upvotes: 1

Quinn Taylor
Quinn Taylor

Reputation: 44769

I think the previous answers have missed the point, or else the asker was pretty unclear. The actual question isn't talking about either array, but rather the array contents:

who is responsible for releasing the objects contained in the array? Is it main() or array2?

Both array1 and array2 are responsible for releasing the objects.

From the NSArray documentation:

"Arrays maintain strong references to their contents—in a managed memory environment, each object receives a retain message before its id is added to the array and a release message when it is removed from the array or when the array is deallocated."

To begin with, each of the objects are retained by the NSArray array1. When you create array2 via -mutableCopy, you get an NSMutableArray which points to the same objects, and retains each of them again. If you were to release array1 at this point, when its dealloc method were called it would release each of the objects it contains. However, array2 has retained them, so the objects won't be destroyed — only when their retain count reaches 0, which would happen if array2 were destroyed and nobody else has retained any of the objects (or when they are removed from array2).

Since collection classes (arrays, sets, dictionaries, etc.) handle retaining and releasing their contents, all you have to worry about is retaining or releasing the collection itself. Since you used -mutableCopy, remember that you have implicitly retained array2, so you should release it when you're done with it.

Upvotes: 13

ThaDon
ThaDon

Reputation: 8068

I reference this guide for Memory Management in Obj-C. He has a section on Arrays and Dictionaries, here's an excerpt:

Arrays, dictionaries etc. generally retain any objects added to them. (When dealing with 3rd party collection type objects, always check the documentation to see if they retain or not). This means that these collections will take ownership of the object, and you do not need to retain before adding.

The comments for the posting are also useful

Upvotes: 1

mcandre
mcandre

Reputation: 24602

It wouldn't make sense for a mutable array to be tied to an immutable array. main() would be responsible for releasing array1.

In my experience however, releasing objects only causes applications to crash. ObjC is fairly good at automatically managing memory. My Cocoa apps don't seem to ever need more memory than they started with, even after running several hours.

Upvotes: -5

Related Questions