- Retaining and Releasing
- Assigning to Instance Variables
- Automatic Reference Counting
- Returning Objects via Pointer Arguments
- Avoiding Retain Cycles
- Migrating to ARC
- Autorelease Pools
- Using Autoreleased Constructors
- Autoreleasing Objects in Accessors
- Supporting Automatic Garbage Collection
- Interoperating with C
- Understanding Object Destruction
- Using Weak References
- Allocating Scanned Memory
Using Weak References
One of the nicest things about Apple’s garbage collection implementation is the existence of zeroing weak references. Pointers that are not retained are often referred to as “weak” in Objective-C documentation that predates the garbage collector. These are references that are allowed to persist beyond the lifetime of the object. Unfortunately, there is no automatic way of telling whether they are still valid.
Weak references were found to be so useful with the garbage collector that they are now also supported by ARC, with slightly different semantics. The ARC implementation provided for backwards compatibility does not support weak references, so they can only be used with ARC on Apple platforms if you restrict yourself to OS X 10.7 or iOS 5 and later.
If you declare an object pointer __weak, you get a zeroing weak reference. This is not counted by the garbage collector when determining if an object is still live and does not increment the object’s reference count when assigned to in ARC mode. If all of the references to an object are weak, it can be destroyed. Afterwards, reading the weak references will return nil.
Weak references are most commonly used in connection with things such as notifications. You will keep a weak reference to an object and keep sending it messages as long as it is referenced elsewhere, then you can have it cleaned up automatically later.
Cocoa now comes with some collections that let you store weak references. Older versions of the Foundation framework provide NSMapTable and NSHashTable as opaque C types, with a set of C functions to use them. These interfaces are still available, but with 10.5, Apple made these two C types into classes.
The NSMapTable type is a general form of NSDictionary that can be used to store any pointer-sized types as both values and keys. With garbage collection, you can use this class to store mappings to and from strong or weak object pointers as well. This is useful for things such as NSNotificationCenter, so that objects can be collected while they are still registered to receive notifications and can be automatically removed from the notification center when this happens.
The example at the start of this section shows an important difference between ARC and GC modes. If you compile and run this example with garbage collection enabled, you will probably see it print an object address. This is because the garbage collector will still see stale temporaries while scanning the stack.
In contrast, this will always print 0 in ARC mode. ARC, unlike GC, is entirely deterministic. Assigning nil to the strong pointer decrements the object’s reference count and triggers deallocation. The weak pointer is zeroed before deallocation begins and so is guaranteed to be zero by the time the fprintf() is reached.