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?
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.
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
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.
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.