The short answer is that using assign
will probably result in memory leaks. Unless you're very careful.
By declaring the array property as retain
, you are indicating that the object should take ownership of the array by sending it a retain
message and, more importantly, that it should send it a release
message when it is no longer interested in keeping the array around. When you use assign
, the object won't send the array any retain
or release
messages. So, in the example you give, there isn't a problem YET. You've created an array with a retain count of one (conceptually) and given it to your object. In this case, the array hangs around in memory with a retain count of 1 just as it would have if you'd used the retain
attribute when declaring the property.
The problem comes when you want to change the value of myArray
. If your property is declared with retain
, an assignment will do something like this:
- (void)setMyArray:(NSArray *)newArray {
if (myArray != newArray) {
[myArray release]; // Old value gets released
myArray = [newValue retain];
}
}
The old myArray
gets sent a release
message indicating that the object is done with it. If the retain count of myArray
drops to zero, it will get deallocated and its memory reclaimed. If the property is declared with assign
, this basically happens:
- (void)setMyArray:(NSArray *)newArray {
myArray = newArray;
}
The object forgets about the array at myArray
without sending it a release
message. Therefore, the array previously referred to by myArray
probably won't get deallocated.
So, it's not the assignment that's a problem. It is the failure to release the array during reassignment that will cause the memory leak. This might not be a problem if another object owns the array.
If another object owns the array, and the array is just being referenced by myArray
, that other object is in charge of making sure the array stays around as long as myArray
needs it and of releasing the array when it's no longer needed. This is the pattern typically used for delegates. You then have to be careful that you don't access myArray
after that other object has released the array it references.
Essentially, this comes down to the question of who owns the array referenced by myArray
. If another object owns it and will handle retaining and releasing it as needed, it's perfectly okay for your object to simply reference it. However, if your object is the owner of myArray
(and will be releasing it in dealloc
), it makes more sense to use the retain
attribute. Otherwise, in order to avoid leaks, you'll require other objects to release the contents of myArray
prior to calling your object's setter, since your assign
setter won't do it for you.