I’ve just read the accepted excellent answer to this question that clarifies the conceptual differences between strong and weak pointers in Objective-C, and I’m still trying to understand the practical differences. I come from a C++ background where these concepts don’t exist, and I’m having trouble figuring out where I would use one vs the other.
Could someone please provide a practical example, using Objective-C code, that illustrates the different uses of strong and weak pointers?
Concept
It’s all about the retain counts. ARC is a convenience, to prevent developers worrying about manually retaining and releasing. At its core, a strong variable will knock up the retain count by 1, whereas a weak variable won’t.
See below:
You can’t get into a situation where a strong variable is referencing an object with a retain count of 0, that defies the core concept of a strong variable. It is worth noting, along side
__weak, there is__unsafe_unretained. This acts just like a weak variable, except it isn’t automatically set to nil once the retain count reaches zero, meaning it will contain a pointer to a random part of memory (and will crash if you access it, you need to nil it yourself). The reason this exists is due to iOS 4 supporting ARC, but not__weak. In most cases, you’d use__weak.The above description is just a practical glance, you can read a lot more in depth using this documentation.
Practical applications
Everything is
__strongby default. If you want weak, you need to use__weak.You would typically use weak variables when you conceptually don’t want to own a particular object. Whilst a car would own its engine and wheels, it wouldn’t own the driver.
Conversely, a driver would own the Car.
If the car owned the driver, we would have a retain cycle. The car owns the driver, and the driver owns the car. If we were to release one, what would happen to the other? The whole concept of retain cycles outweighs the scope of this question, but you can read about it here.
The same concept applies to programming patterns, for example delegates. For a table view, the view controller would own the table view, but the table view doesn’t own the view controller (Which is uses as a delegate)
Gotchas
One serious use of
__weakis within blocks. Without them, you’re at serious risk of causing retain cycles without realising. Again, this outweighs the scope of this question, but see here for more information.Analogy to C++
Within TR1 you have the ability to use shared pointers, these allow you to put a heap allocated object within a stack allocated one, and it manages the memory for us. It does this through the use of reference counting. Everytime you pass the shared pointer to another variable, the reference count is incremented. This analogises to assigning to a strong variable in Obj-C.