
A memory model in Objective-C
A very significant improvement in Objective C 2.0 is its memory model. The countless remnants of problems from the first Objective-C implementations as a preprocessor that induced C were cleaned up. In older versions, Objective-C objects were simply C structures, containing a pointer to their classes in their first fields, and its pointers were just able to receive messages when you wanted to send them.
Now every object pointer comes into one of the following categories: weak
, strong
, autoreleasing
, and unsafe unretained
. When ARC is disabled, the programmer is responsible to take care of them all, being sure that they are all safe, for the reason that all those pointers just fit the last category.
The default category (type qualifier) is a strong
pointer; they are largely correspondent to the consequences of writing flawless defensive retain/release code. Assigning to a strong
pointer is relative to retain the new value and release the old value, because owning references are stored in those pointers.
You need to use autoreleasing
pointers in order to store values that are autoreleased. In Objective-C, such pointers are the most habitual form of non-owning reference pointers; they are variables on the heap storing autoreleased values. An owning reference pointer, also known as an instance variable, will only be autoreleased when it is stored to a non-owning reference pointer, known as an autoreleasing variable. If you simply store an autoreleased reference pointer, you will have a simple attribution.
In order to decrease the quantity of release and retain statements in a crucial piece of code, it's possible to make use of _autoreleasing
, one of the four ARC type qualifiers. However, since the objects will be included in the autoreleasing pool and ARC can commonly eliminate this, it's usually not required to use this type qualifier, besides the fact that is can make things slower.
Weak is the last category (type qualifier) of pointer. If you used the garbage-collector mode in Objective-C, you probably already met weak
pointers by storing an object in such a pointer. It's not seen as an owning reference pointer (for instance, a variable), and when the object is deallocated, this point is immediately set to nil.
We can count many differences between GC and ARC mode, but the very important one is about ARC being deterministic. It's possible to see it through weak
pointers. See the following code for an example:
id strong = [NSObject new]; __weak id weak = strong; strong = nil; NSLog(@"%@", weak);
Firstly, since in the garbage collection mode__weak
is not granted for on-stack variables, the preceding code won't even pass through compilation. However, what would happen if the weak declaration is moved to somewhere it's valid? We presume that at this point, the object's last reference is already gone. However, the log statement will show you that the object is still there, alive. Relying on the optimizations that the compiler is running, the collector can possibly see its references on the heap if you run the collector by force.
This piece of code will be compiled in the ARC mode—now, weak variables are allowed on the heap.