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?.
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
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.
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 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
).
How IBoutlet hold initial value being weak? Means some other strong object is pointing?
When the scene is loaded from the storyboard the button is added to the view hierarchy before the reference is assigned to the @IBOutlet
property. Since the button is in the view hierarchy there is a strong reference to it.
When you say something like
self.buttonOutlet = UIButton()
The only reference to the new button is a weak property and the compiler warns you that the object will be immediately released.
You can use a local variable to hold a strong reference until the button is added to the view hierarchy.
let newButton = UIButton()
self.view.addSubview(newButton)
self.buttonOutlet = newButton
Related Topics
Error in Xcode 6 - View Controller Does Not Have an Outlet Named (Subview)
Accessing Core Data Stack in Mvvm Application
Alamofire: Finished with Error - Code: -1001
Doing Undo and Redo with Cglayer Drawing
How to Set an Nscalendarunitminute Repeatinterval on iOS 10 Usernotifications
Uiscrollview Pauses Nstimer While Scrolling
Cabasicanimation Rotate Returns to Original Position
Swift 3: Replace C Style For-Loop with Float Increment
Fetching Selected Attribute in Entities
Set Text Color and Font for Uidatepicker in iOS8/Swift
Xmlparser.Sharedparser.Decode() in Swift3
React Native Xcode Project Product Archive Fails with Duplicate Symbols for Architecture Arm64
How to Read Plist Without Using Nsdictionary in Swift
Tap Gesture on Animating Uiview Not Working
How to Connect Multiple Buttons in a Storyboard to a Single Action