The LLVM Compiler 3.0 introduces four new ownership qualifiers: __strong
, __autoreleasing
, __unsafe_unretained
, and __weak
. The first three are available even outside ARC, as per the specification.
As Joshua indicates, by default all pointers are implied to be __strong
under ARC. This means that when an object is assigned to that pointer, it is retained for as long as that pointer refers to it. This is fine for most things, but it opens up the possibility for retain cycles, as I describe in my answer here. For example, if you have an object that contains another object as an instance variable, but that second object has a strong link back to the first one as its delegate, the two objects will never be released.
It is for this reason that the __unsafe_unretained
and __weak
qualifiers exist. Their most common use is for delegates, where you'd define a property for that delegate with the weak
or unsafe_unretained
attribute (assign
is effectively unsafe_unretained
), and then match that by marking the respective instance variable with __weak
or __unsafe_unretained
. This means that the delegate instance variable will still point back at the first object, but it will not cause that object to be retained, thus breaking the retain cycle and allowing both objects to be released.
Beyond delegates, this is useful to break any other retain cycles that might form in your code. Helpfully, the Leaks instrument now includes a Cycles view, which shows retain cycles it discovers in your application in a graphical manner.
Both __unsafe_unretained
and __weak
prevent the retention of objects, but in slightly different ways. For __weak
, the pointer to an object will convert to nil
on the deallocation of the object it points to, which is very safe behavior. As its name implies, __unsafe_unretained
will continue pointing to the memory where an object was, even after it was deallocated. This can lead to crashes due to accessing that deallocated object.
Why would you ever use __unsafe_unretained
then? Unfortunately, __weak
is only supported for iOS 5.0 and Lion as deployment targets. If you want to target back to iOS 4.0 and Snow Leopard, you have to use the __unsafe_unretained
qualifier, or use something like Mike Ash's MAZeroingWeakRef.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…