Should IBOutlets be strong or weak under ARC?
The current recommended best practice from Apple is for IBOutlets to be strong unless weak is specifically needed to avoid a retain cycle. As Johannes mentioned above, this was commented on in the "Implementing UI Designs in Interface Builder" session from WWDC 2015 where an Apple Engineer said:
And the last option I want to point out is the storage type, which can
either be strong or weak. In general you should make your outlet
strong, especially if you are connecting an outlet to a subview or to
a constraint that's not always going to be retained by the view
hierarchy. The only time you really need to make an outlet weak is if
you have a custom view that references something back up the view
hierarchy and in general that's not recommended.
I asked about this on Twitter to an engineer on the IB team and he confirmed that strong should be the default and that the developer docs are being updated.
https://twitter.com/_danielhall/status/620716996326350848
https://twitter.com/_danielhall/status/620717252216623104
When should I use Strong vs Weak for IBOutlets (further clarification)
Most outlets for subviews don't need to be strong references because, after all, they're subviews loaded as part of a view hierarchy. As long as the top-level view exists, and as long as you don't go removing the subviews from their parents, the subviews in the view hierarchy will be retained by their parents for the lifetime of the top-level view.
In the days before ARC, some people were happy to rely on the view hierarchy to retain their views for them and so set their outlet properties to assign
. Others didn't like the idea that a hiccup in the view hierarchy could leave them with a handful of dangling pointers, and so set their properties to retain
. ARC gives us zeroing weak references, so that your outlets will be set to nil
if the objects they point to are deallocated, and that makes using weak references for outlets seem a lot safer. On the other hand, if you want to maintain a reference to a view even if the view hierarchy that contains is is deallocated, you should set that reference to strong
.
Since your view controller is responsible for the view hierarchy it manages (i.e. "owns"), it should have a strong reference to the top-level view. You don't need to worry too much about this, as the view
property of any UIViewController-derived view controller is set to retain
(i.e. strong
).
weak or strong for IBOutlet and other
A rule of thumb
When a parent has a reference to a child object, you should use a strong
reference. When a child has a reference to its parent object, you should use a weak
reference or a unsafe_unretained
one (if the former is not available). A typical scenario is when you deal with delegates. For example, a UITableViewDelegate
doesn't retain a controller class that contains a table view.
Here a simple schema to present the main concepts.
Suppose first A,B and C are strong
references. In particular, C has a strong
ref to its parent. When obj1 is released (somewhere), the A reference doesn't exist anymore but you have a leak since there is a cycle between obj1 and obj2. Speaking in terms of retain counts (only for explain purposes), obj1 has a retain count of 2 (obj2 has a strong
reference to it), while obj2 has a retain count of 1. If obj1 is released, its retain count is now 1 and its dealloc
method is not called. obj1 and obj2 still remain in memory but no one has a reference to them: Leak.
On the contary, if only A and B are strong
refs and C is qualified as weak
all is ok. You have no leaks. In fact, when obj1 is released, it also releases obj2. Speaking in terms of retain counts, obj1 has a retain count of 1, obj2 has a retain count of 1. If obj1 is released, its retain count is now 0 and its dealloc
method is called. obj1 and obj2 are removed from memory.
A simple suggestion: Start to think in terms of object graph when you deal with ARC.
About your first question, both solutions are valid when you deal with XIBs. In general weak
references are used when you deal with memory cycles.
Concerning XIBs files, if you use strong
you need to set nil
in viewDidUnload
since if you don't do it, in memory low conditions, you could cause unexpected leaks. You don't release them in dealloc
because ARC will do it for you. weak
instead doesn't need that treatment since, when the target object is destroyed, those values are set as nil
automatically. No dangling pointers anymore.
If you are interested in, I really suggest you to read friday-qa-2012-04-13-nib-memory-management by Mike Ash.
About your second question, if you need to support iOS 4, instead of weak
you have to use unsafe_unretained
.
Within SO there are a lot of questions/answers. Here the main ones:
How do I replace weak references when using ARC and targeting iOS 4.0?
What kind of leaks does automatic reference counting in Objective-C not prevent or minimize?
using ARC, lifetime qualifier assign and unsafe_unretained
strong / weak / retain / unsafe_unretained / assign
Hope that helps.
Update
As per shaunlim's comment, starting from iOS 6 viewDidUnload
method is deprecated. Here I really suggest to see Rob's answer: iOS 6 - viewDidUnload migrate to didReceiveMemoryWarning?.
IBOutlets Strong or Weak - Does it Actually Make a Difference to Memory Management? (ARC)
IBOutlets can declared weak because they will be created during XIB parsing and added to the UIView stack...so you don't need a strong reference to the object.
When you declare an IBOutlet weak you ensure that when the main UIView of UIViewcontroller disappear every subview will be deleted without any memory leak.
When should I use the weak or strong qualifier with IBOutlets?
In general: if you are making an outlet to a subview of the ViewControllers subview it should be weak. The object exists as long as the top view exists (between viewDidLoad and viewDidUnload). As iOS 5 ARC automatically nullifies weak links, when the viewController unloads its view and view hierarchy is destroyed, your outlet is automatically set to nil.
But maybe you want to create another object in your nib file (a model object). As this object is not under the view hierarchy, you need to make the iboutlet strong. If you make it weak linked, the object will be autoreleased since no other object has a strong reference to it and ARC will release it and set nil to your IBOutlet. This is not the case of a subview since its superview mantains a strong link with it.
IBOutlets strong or weak
Instance variables under ARC are strong by default. And they are neither atomic nor nonatomic, since they are just instance variables and not accessor methods. The atomic/nonatomic flags are related to multi threading. They specify whether or not the accessor methods should be atomic. When an accessor is atomic, the execution can't change to an other thread in the middle of the accessor method. When it's nonatomic, there is no such restriction.
Note: IBOutlet is a typedef of nothing. It's just a flag for Interface Builder and has no memory related functions.
Related Topics
React-Native, How to Get File-Asset Image Absolute Path
Swift - Integer Conversion to Hours/Minutes/Seconds
How to Debug 'Unrecognized Selector Sent to Instance' Error
How to Return Value from Alamofire
Ios App With Framework Crashed on Device, Dyld: Library Not Loaded, Xcode 6 Beta
How to Force View Controller Orientation in iOS 8
Change User Agent in Uiwebview
Save String to the Nsuserdefaults
How to Customize the Background/Border Colors of a Grouped Table View Cell
Core Data: Quickest Way to Delete All Instances of an Entity
How to Get the Root Directory of My iOS App
How to Remove Constraints Programmatically That Is Added from Storyboard
How to Store Custom Objects in Nsuserdefaults
Can't Use Swift Classes Inside Objective-C
What Are Different Types of Notifications in iOS and How to Configure Them Correctly