1

I read in the apple documentation about copyWithZone :

"The returned object is implicitly retained by the sender, who is responsible for releasing it".

So if I write this :

 - (id)copyWithZone:(NSZone *)zone {
        MyObject* obj = [[[[self class] allocWithZone:zone] init] autorelease];
        [obj fillTheObj];

        return obj;
    }

and I call :

MyStuff* obj = [varobj copy];

will obj be retained? What about the retain count if I don't set autorelease?

gunr2171
  • 16,104
  • 25
  • 61
  • 88
Oliver
  • 23,072
  • 33
  • 138
  • 230

1 Answers1

3

Do not autorelease it in your copyWithZone method or you won't own it (and likely won't be able to even do anything with it).

Remove the autorelease and obj will be appropriately retained in the MyStuff copying. You simply need to release it when you're done with it.

The Apple sentence is saying that the sender -- which is your MyStuff *obj initialization -- has ownership and needs to release it. "Sender" refers to the object that sent the copy message, not your copyWithZone method.

Matthew Frederick
  • 22,245
  • 10
  • 71
  • 97
  • @Matthew Frederick : ok, so there is no IMPLICIT retain as Apple documentation says. It's an explicit one due to your code ? – Oliver Jan 08 '11 at 11:14
  • Read my edited version. Because the sender is performing a copy, it now implicitly retains it. Which is pretty explicit to me, but the word "retain" isn't used anywhere, making it implicit. – Matthew Frederick Jan 08 '11 at 11:15
  • @Matthew Frederick : ok, so what if I remove the autorelease ? There is a retain inside the call, AND an implicit one outside the call, isn't it ? In other words, what is IMPLICIT here ? I only see explicit things, or there will be two retains. – Oliver Jan 08 '11 at 11:22
  • Remove the autorelease and just release the object when you're done with it. The allocWithZone and init in the copyWithZone method is what does the retaining, which gets passed to your caller. This is what happens with all `copy` requests: the retention occurs in the copy method and ownership is passed to the message sender. The implicit part is that the sender is being given ownership despite not using the word "alloc" or "retain." – Matthew Frederick Jan 08 '11 at 11:31
  • @Matthew Frederick : OK. I've been told that if I write a method in which the word "copy" appears, its return value is automaticaly retained. That was confusing me so I imagined a non explicit retain, that would cause here a double retain. SO do you confirm that if I write a method called DoNotCopyAnything, that does not retain anything in it, its return value won't be retained by the framework or anything else. – Oliver Jan 08 '11 at 13:42
  • 2
    There is no magic going on. It will do whatever you implement. It's just that alloced objects are already retained. – Eiko Jan 08 '11 at 14:07
  • Like @Eiko said, it's not the naming of the method that does the retaining, it's the actual code. It's convention -- and good convention to stick to -- that says if you're returning a retained object you should use the words "new," "alloc," or "copy". – Matthew Frederick Jan 08 '11 at 18:37