6.5 Retain cycles
A retain cycle is something that must be avoided. If an object A retains an object B, and that B
and C are mutually retaining each other, B and C are forming a retain cycle.
A → B C
If A releases B, B will not be deallocated since it is still retained by C. And C cannot be deallocated
since it is retained by B. However, A was the only reference to that cycle, so it is no more eachable.
Retain cycles usually lead to memory leaks. This is why, in a tree structure for instance, a node
usually retains its children, but a child usually does not retain its parent.
6.6 Garbage collector
Objective-C 2.0 (cf. Section 1.2 on page 6) implements a garbage collector. In other words, you
can delegate all the memory management and do not care about retain and release any more. A
great choice of Objective-C was to make the garbage collector an optional feature : you can decide
if you want to precisely control the life-time of objects, or if you want to make less bug-prone code.
The garbage collector is enabled or disabled for the whole program.
If the garbage collector is enabled, retain, release and autorelease are redefined to do noth-
ing. Thus, code that was written without garbage collection can theoretically be recompiled easily
for the garbage collector. “Theoretically” means that many subtleties should be handled regarding
resource liberation. Thus, it is not easy to write unified code for both cases, and developers are
even advised again that practice. Those subtleties are detailed in Apple’s documentation [2]. The
next four sections are quoting some of these difficulties, to highlight the most important points
that should be properly studied.
6.6.1 finalize
In a garbage-collected environment, the non-deterministic order of the destruction of the objects
is does not suit very well the use of dealloc. A finalize method has been added to NSObject
to split the destruction into two steps : resources release and effective deallocation. But a “good”
finalize method is subtle and tricky. Some conception constraints should be taken in account [2].
6.6.2 weak, strong
It is not very common to see __weak and __strong explicitely used in a declaration. However,
their knowledge helps understanding some new difficulties related to the garbage collector.
By default, a pointer to an object is using the __strong attribute : this is a strong reference.
It means that the object cannot be destroyed as long as this reference remains. This is the expected
behaviour : when all (strong) references have disappeared, the object can be collected and released.
In some cases, it is useful to disable that behaviour : some collections should not increase the
lifetime of the objects they are holding, because it would prevent these object to be ever destroyed.
In this case, these collections are using weak references, with the __weak keyword. NSHashTable
is an example (cf. section 11.1 on page 54). A __weak reference is automaticaly nullified (set to
nil) when the referenced object has disappeared.
A very relevant example is the Notification Center of Cocoa, which is out of the scope of pure
Objective-C, and is not detailed in the present document.
6.6.3 NSMakeCollectable()
Cocoa is not the only API of MacOS X. Core Foundation is another one; they are compatible and
can share data and objects, but Core Foudation is a procedural API written in C only. At first
sight, the garbage collector cannot work with Core Foundation pointers. This problem has been
addressed, and it is possible to use Core Foundation without memory leaks in a garbage-collected
environment. The NSMakeCollectable documentation is a good starting point to know the tricks.
6.6.4 AutoZone
The Objective-C garbage collector created by Apple is called AutoZone. It has been publicly
released as Open-Source [1]. Evolutions are planned for MacOS X10.6.
48