ARC has absolutely nothing to do with garbage collection algorithms. Automated Reference Counting (ARC) uses reference counting as its underlying mechanism for making decisions about reachability of an object. In contrast, garbage collection algorithms maintain a list of "root" objects (e.g. local variables, static variables, thread objects) and use these roots to traverse object graphs to check for reachability of an object. This process is non-deterministic, in the sense that you never know when the GC algorithm is going to run, and when objects that are no longer referenced would be garbage collected. All you know is that they eventually will be garbage collected, but "eventually" may mean a really long time.
Since GC uses graph traversal for reachability analysis, it does not care about cycles in a graph: if an object is reachable from some set of objects that are not in the root set, it is still considered garbage and would be collected. Therefore, you do not need to worry about retain cycles - a very real problem that you need to always keep in mind when working with reference counting systems.
Reference counting is much simpler than garbage collection: each object has a reference count shown in the diagram, retain
increments it, and release
decrements it. Once the count gets to zero, the object gets destroyed. That's really it! All that ARC does is automating the insertion of calls to retain
and release
. In fact, it is not possible to tell from this diagram alone if we are talking about the new ARC, or a pre-ARC memory management of Cocoa. Under a reference counting system you know exactly when your object is going to be released - it is going to happen as soon as its reference count reaches zero. Autoreleasing makes this a little less visible to you, because the last reference may be released outside of your code, but that does not make the process non-deterministic. Moreover, the language lets you take full control over autoreleasing by letting you make your own autorelease pools.