Question

I'm an objective-c newbie and I just can't understand why it is a bad idea to release object that doesn't belong to me.

Let's say I have this in the method called Europe

//initForStringTheory is a class init method;
Collider *LHC = [Collider initForStringTheory]; 

//Colliders is a NSMutableArray
[Colliders addObject: LHC]  

[LHC release]

I'm adviced not to release LHC in Europe as Europe does not own LHC, it only has a pointer to it. And therefore I should make good use of the autorelease pool and do

//newCollider is a pointer for the newly created instance in initForStringTheory
return [newCollider autorelease]; 

in initForStringTheory. But why?

Doesn't the pointer in Europe points to the instance too? Why can't I just release LHC in Europe instead of returning a autoreleasing newCollider in the init method?

Était-ce utile?

La solution 2

It's all a question of what initForStringTheory returns - if this is a convenience initialization method such as [NSArray arrayWithObjects...] or [NSString stringWithFormat...], it creates an autoreleased instance that you do not need to release after adding it to your collection. However, if this is an initialization that returns an initialized non-autoreleased instance, it is your responsibility to release the local instance definition in your method right after adding it to the collection.

The retain count of the object is incremented by 1 when it is added, so you don't want it to be 2 because you haven't released/autoreleased it after instantiation (would result in a memory leak because the object will never become deallocated, even when it's out of the array).

Read this: http://developer.apple.com/library/mac/#documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html

Autres conseils

Stavash basically covered that whether you release it depends on whether the method returned a retaining instance or not.

However, you shouldn't really ever need to know what a method does in order to use memory management correctly. Cocoa MRC memory management follows rules on what methods do based on the name of the method. According to the rules, methods whose names start with alloc, retain, new, copy, or mutableCopy return a retained instance, and the caller are responsible for releasing it. Methods with all other names return a non-retained instance, and the caller should not release it.

So, assuming (of course, that's a big assumption) that initForStringTheory follows the rules properly, it should not return a retaining instance (that does not mean it is necessarily autoreleased; it may be retained by something else and simply returned directly to you).

Another part of the problem is that it is highly unconventional to have a class method named init.... Generally, instance methods starting with init are constructors, which are run immediately on the result of an alloc which created the instance. So what the hell does a class method named init... do? Also, by convention there is a special rule for init methods, that it "consumes" the retained instance returned by alloc, and returns a (not necessarily the same) retained instance. But how would that apply to this case, where it is called on a class? Would it "consume" a retain count on the class object (which does nothing), and then return a retained instance? Nobody knows.

So in conclusion, this code really needs to be re-written. Definitely do not have class methods named init.... And make sure that all the methods you write have memory management behaviors that correctly follow the rules, based on their names.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top