In our current code, the properties of XIB controls are added with weak. However, we encounter some crashes due to accessing wild pointers of controls when a memory warning occurs. Colleagues from our architecture team said that they had specifically consulted Apple's technical staff before, and the reply was that strong should be used for modification, as it would make the memory more stable. They also mentioned that the statement in the official documentation is incorrect and hasn't been updated. May I ask whether strong or weak should be used for XIB control properties? What is your latest standard answer?
The standard answer is "it depends." Without more context about your crash, I can't know which recommendation is correct for your needs, but the right choice for any situation comes down to understanding the fundamentals of ARC and UIKit view composition. Xcode uses weak
when you drag out an outlet as its default, so that's a hint as to a good default, but let's look at some common examples to understand things in terms of memory references.
Important: In the diagrams that follow, each solid arrow represents a strong reference and dotted arrows are weak references. Consider these diagrams conceptual — they are not meant to confer specific system implementation details.
The most common case is that a subview is added to the parent view when designing the view in Interface Builder. When that view is created in memory by instantiating the XIB, the parent view's subviews
array contains that child view, and thus has a strong reference to it, since it is in the view hierarchy by virtue of being in the subviews array. If the IBOutlet
property for that child view is weak
(the left diagram), the parent view has one strong memory reference to that child view. If all you do is twiddle properties to customize the subview — say to set the text or color of a label — then that child view remains in memory because the subviews
array having a strong reference to it. Using weak
is fine in this case.
What happens if this weakly-held view is used in a way that means this child view is sometimes removed and then added back to the view hierarchy? When it's removed from the view hierarchy, the references between child and parent views are removed, so nothing has a strongly held reference to it, so the subview is deallocated. Perhaps that's what you're encountering, or why you received that specific recommendation from Apple in the past.
Is that subview deallocating after removing from the view hierarchy good or bad? If it's weakly held, that might help keep your overall app memory footprint down, because you're not holding potentially large view hierarchies in memory when they're not needed. But if that subview is often added back to the view hierarchy later or is expensive to instantiate, then there's a cost to recreating it, and perhaps managing your own strong reference to it is the better choice (the right side of the diagram).
Note that what I write above is specifically for views coming from an XIB. Storyboards add view controllers into the mix, so there's a bit more to consider because it's easier to accidentally create strong reference cycles, and so weak
is often the better choice here. Let's consider this second diagram so we understand how a storyboard can be different:
On the left, we have a view controller with its view
property set up, and that view controller also has a direct reference to a subview, strongly referenced. What happens if there's a reason for the view controller to nil its view
, such as when a memory pressure notification is received? That's the right diagram, where the strong reference to a nested subview accidentally causes an entire view hierarchy to be retained in memory, which defeats the purpose of the view controller removing its view in response to memory pressure, and thus is a clear bug in the view controller's implementation. Thus with storyboards, using weak properties for IBOutlet
view properties is often the better default choice, as it avoids unexpected retain cycles.
— Ed Ford, DTS Engineer