Gestión de la memoria al copiar objetos

I know that my question has already been discussed on StackOverflow but i found the answer not complete for my needs. So the question is:

NSMutableArray *firstArray = [[NSMutableArray alloc] initWithObjects: obj1,obj2,nil];
NSMutableArray *secondArray = [[NSMutableArray alloc] init];
secondArray = [firstArray mutableCopy];

what is retain count for the secondArray now? 2 or 1? Should i release it twice or just once? Does copy or mutableCopy increases retain count of the COPYING (secondArray in this event) object?

preguntado el 08 de noviembre de 11 a las 11:11

2 Respuestas

You should never care about the absolute retain count. Only that you're "balanced", that means for every alloc, new*, copy, mutableCopy y retain you need a corresponding release or autorelease (when not using ARC, that is).

If you apply this rule to each line you can see that your second line has an alloc, but there's no release. In fact, it's absolutely useless to allocate an instance here since you're not interested in it anyway. So it should simply read:

NSMutableArray *firstArray = [[NSMutableArray alloc] initWithObjects: obj1,obj2,nil];
NSMutableArray *secondArray = [firstArray mutableCopy];
// There is no third line.

But let's discuss your original code and see what happened:

NSMutableArray *firstArray = [[NSMutableArray alloc] initWithObjects: obj1,obj2,nil];
NSMutableArray *secondArray = [[NSMutableArray alloc] init];
// secondArray points to a new instance of type NSMutableArray
secondArray = [firstArray mutableCopy];
// You have copied another array (created a new NSMutableArray
// instance) and have overwritten the pointer to the old array.
// This means that the instance allocated in line 2 is still there
// (was not released) but you don't have a pointer to it any more.
// The array from line 2 has been leaked.

In Objective-C, we often speak of propiedad: there are very few methods that make you the "owner" of an object. These are:

  • alloc
  • new*, como en newFoo
  • copy y mutableCopy
  • retain

If you call these, you get an object for which you are responsable. And that means you need to call a corresponding number of release y/o autorelease on these objects. For example, you're fine if you do [[obj retain] retain]; y entonces [[obj autorelease] release];

respondido 08 nov., 11:15

I'd add that you have two objects which are owned and need to be released at some stage. And you're right - the retainCount is unimporant - only worry about balancing owning calls with releasing calls. - Abizern

Actually secondArray has been allocated and used somewhere far away in the code. I wrote it in second line just for convenience. So if i got you right in order to avoid memory leaks i should release secondArray first and this would be absolutely valid? - Andrey Chernukha

@AndreyChernukha: You only release the object pointed to by secondArray once you're finished with it. release medio: From this line on, I won't be needing that object any more; it may be deallocated. autorelease medio: Soon, I won't be needing it any more; but it should stay alive at least until I leave this method. (That's not 100% correct but close enough to the truth to be useful) - DarkDust

NSMutableArray *firstArray = [[NSMutableArray alloc] initWithObjects: obj1,obj2,nil];
NSMutableArray *secondArray = [[NSMutableArray alloc] init];
secondArray = [firstArray mutableCopy];

What is happening is that you've created a memory leak. You just lost the reference assigned to secondArray when you overwrote it with the mutableCopy of firstArray with this line.

secondArray = [firstArray mutableCopy];

If you then release secondArray twice, the program will crash because you're then overreleasing the mutable array assigned by

secondArray = [firstArray mutableCopy];

What you need to do is to make sure you're not overwriting retained references by mistake, and balance retains with releases.

respondido 08 nov., 11:15

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.