I’m using [self retain] to hold an object itself, and [self release] to free it elsewhere. This is very convenient sometimes. But this is actually a reference-loop, or dead-lock, which most garbage-collection systems target to solve. I wonder if objective-c’s autorelease pool may find the loops and give me surprises by release the object before reaching [self release]. Is my way encouraged or not? How can I ensure that the garbage-collection, if there, won’t be too smart?
Share
This way of working is very discouraged. It looks like you need some pointers on memory management.
Theoretically, an object should live as long as it is useful. Useful objects can easily be spotted: they are directly referenced somewhere on a thread stack, or, if you made a graph of all your objects, reachable through some path linked to an object referenced somewhere on a thread stack. Objects that live “by themselves”, without being referenced, cannot be useful, since no thread can reach to them to make them perform something.
This is how a garbage collector works: it traverses your object graph and collects every unreferenced object. Mind you, Objective-C is not always garbage-collected, so some rules had to be established. These are the memory management guidelines for Cocoa.
In short, it is based over the concept of ‘ownership’. When you look at the reference count of an object, you immediately know how many other objects depend on it. If an object has a reference count of 3, it means that three other objects need it to work properly (and thus own it). Every time you keep a reference to an object (except in rare conditions), you should call its
retainmethod. And before you drop the reference, you should call itsreleasemethod.There are some other importants rule regarding the creation of objects. When you call
alloc,copyormutableCopy, the object you get already has a refcount of 1. In this case, it means the calling code is responsible for releasing the object once it’s not required. This can be problematic when you return references to objects: once you return it, in theory, you don’t need it anymore, but if you callreleaseon it, it’ll be destroyed right away! This is whereNSAutoreleasePoolobjects come in. By callingautoreleaseon an object, you give up ownership on it (as if you calledrelease), except that the reference is not immediately revoked: instead, it is transferred to theNSAutoreleasePool, that will release it once it receives thereleasemessage itself. (Whenever some of your code is called back by the Cocoa framework, you can be assured that an autorelease pool already exists.)It also means that you do not own objects if you did not call
alloc,copyormutableCopyon them; in other words, if you obtain a reference to such an object otherwise, you don’t need to callreleaseon it. If you need to keep around such an object, as usual, callretainon it, and thenreleasewhen you’re done.Now, if we try to apply this logic to your use case, it stands out as odd. An object cannot logically own itself, as it would mean that it can exist, standalone in memory, without being referenced by a thread. Obviously, if you have the occasion to call
releaseon yourself, it means that one of your methods is being executed; therefore, there’s gotta be a reference around for you, so you shouldn’t need toretainyourself in the first place. I can’t really say with the few details you’ve given, but you probably need to look intoNSAutoreleasePoolobjects.