Whenever I am doing asynchronous network requests it could be that on arrival of the request self is already nil (e.g. the ViewController is already dismissed).
To prevent this I am usually capturing self as weak:
future.onSuccess(context: Queue.main.context, callback: { [weak self] result in
if let strongSelf = self {
// Do some stuff with self, which is now guaranteed to be not nil
// strongSelf.someMethod()
}
})
Or I could capture self as unowned:
future.onSuccess(context: Queue.main.context, callback: { [unowned self] result in
// Do some stuff with self
// self.someMethod()
})
I do not care about the request returning, because when the request is returning at a point in time when the ViewController is already dismissed I have nothing to show from the request. So I do not want to keep self "alive" with the closure.
My question is now - is it enough to capture self as unowned in this case? Or do I have to do all the time the nil checking with [weak self]? What happens in case of unowned capturing with the request when it arrives and self is already nil - is the closure also still alive and would execute and would trigger a runtime error on accessing nil? Or would the closure also be deallocated together with self and the request would run into the "void"?
Or can I forget both weak and unowned in this case because when self get's deallocated the closure will also be deallocated and so there is no danger of accessing nil on arrival of the request?
PS: I know that there are already many questions-answers on this topic but I could not find an answer in the case I do not care about the async arrival.
If you capture self without weak or unowned keywords, your view controller will be retained by the closure and will not deallocate before the closure dies. The difference between weak and unowned is that weak is an Optional and requires conditional binding as a safety check. On the other hand, unowned is not as fail-safe. It assumes that your view controller is still alive and it will crash if it is not. For more information see this answer.
You do not want to use unowned in this case, because if the object is deallocated before the call finishes, you have a dangling reference that is not set to nil. If you try to use this reference when the request finishes, the app will crash.
As an aside, if you really don't need the response anymore, you should also cancel the request when the view controller is deallocated. If you use NSURLSession, you always get a NSURLSessionTask reference which can be cancelled. So, one would often combine the use of [weak self] pattern in the closure with code that saves an additional weak reference to the NSURSessionTask and have a deinit conditionally cancel that.
Related
I´m trying to integrate Face/Touch ID Login and I saw [unowned self] in Apple's documentation, inside a closure. What is that and what are the benefits?
Example code:
let context = LAContext()
var error: NSError?
if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
let reason = "Identify yourself!"
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason) {
[unowned self] (success, authenticationError) in
DispatchQueue.main.async {
if success {
print("Authenticated!")
} else {
// error
}
}
}
} else {
// no biometry
}
Long story short, it's the same as weak!, since unowned references are just weak references that are guaranteed to have a value.
unowned is used when you're sure that the reference will NEVER be nil, and therefore, it can only be evaluated with non nil values.
Like weak references, an unowned reference does not keep a strong hold on the instance it refers to. Unlike a weak reference, however, an unowned reference is assumed to always have a value. Because of this, an unowned reference is always defined as a non-optional type. (Apple Docs)
Check this other answer:
What is the difference between a weak reference and an unowned reference?
Docs: ARC Documentation
The unowned qualifier, like weak, prevents the closure from establishing a strong reference to to self which can be helpful in preventing strong reference cycles. The benefit of unowned over weak is that it’s a tad more efficient in optimized builds, not requiring it to keep track of this reference and go back and set it to nil when the object to which it references is deallocated. The unowned reference also is not an optional, meaning that you don’t have to unwrap it, eliminating syntactic noise and simplifying one’s code.
But you obviously can’t use unowned in any situation where the object might be deallocated, because it obviously can no longer keep a reference to the memory for a deallocated object.
Interestingly, the evaluatePolicy(_:localizedReason:reply:) documentation says, “This method asynchronously evaluates an authentication policy.” Any time you’re dealing with an asynchronous method, it is not advisable to use unowned, because you cannot be assured that the object in question hasn’t been deallocated in the intervening time. Only use unowned in those specific situations where you know, for a fact, that the closure cannot be called if the object has been deallocated. That would not appear to be the case here.
Bottom line, use unowned to avoid strong reference cycles and where you want cleaner, slightly more efficient code. But only do so when you know that it is impossible for the object to be deallocated before closure is called.
After reading some articles and developer guide of apple, i'm still confused about Capture List in closure.
What does it mean "capture", how does it work behind the scene in terms of unowned self and weak self? how the closure use self without owning the object?
I thought it like making a copy of that object so when it get finished it's passed from the stack like value type, but i guess that i'm wrong.
I'm hoping that someone here can make it more easier and clear for understanding, or linked me to a good article that answering this specific question.
Thanks for advance
My understanding, and it might be a bit simplified, is that it is about ownership and holding on to an object, meaning that as long as we claim ownership of an object it can not be freed from memory even another part of the code sets it to nil or similar.
With weakwe say that it is okay to destroy the object and that we will only use it if it is still around.
So when declaring self as weak in a closure we say that if self is still around when it's time to execute the closure we do so normally otherwise the closure will silently be ignored without generating an error.
It's mainly to do with reference counting. Any instance that is used inside a closure (but was declared outside) is strongly referenced (i.e. its reference count is incremented). This can lead to retain cycles, e.g.
class MyClass {
var myClosure: (() -> Void)!
init() {
myClosure = {
self.foo()
}
}
func foo() {
}
}
In the above example the instance of MyClass retains a reference to myClosure and vice versa, meaning that the MyClass instance will stay in memory forever.
You can also have more complex/harder-to-spot retain cycles, so you need to really pay attention and if you ever have any doubts add some print calls to your class' deinit methods just to make sure (or use Instruments).
In order to avoid these issues you can mark objects being captured in closures as unowned or weak. This means that their reference count won't be increased and you can avoid these retain cycles. The above example could have either been done this way:
myClosure = { [weak self] in
self?.foo()
}
or, better yet for this example, this way:
myClosure = { [unowned self] in
self.foo()
}
While the first way is always safe and what you will more likely do, the unowned version is easy to reason in this example because you know that myClosure won't outlive self. However, if you're not 100% sure that self will always outlive the closure use weak.
Also note that you can mark how to capture multiple objects used inside the closure, just separate it by commas, e.g.
myClosure = { [weak self, unowned bar] in
self?.foo(bar)
}
If we keep in mind that captured values are strong references in closures by default, we can assume that this can create retain cycles (bad stuff).
A capture list is an array of variables you can pass into a closure. The purpose of capture lists is to change the strenght of the variables that are passed in. This is used to break retain cycles.
For instance:
// strong reference
[label = self.myLabel!] in
// weak reference
[weak label = self.myLabel!] in
// unowned reference
[unowned self] in
I use [weak self] when I have a completion block that refers to properties of my class object. However, sometimes I have a completion block that doesn't refer to any properties, but the class object could disappear and deinit. Should I be using [weak self] or not? It usually gives a warning Variable 'self' was written to, but never read when I do...
doSomeFunction() { [weak self] in
// No references to self here
}
Capturing the variables, happens only when you use it internally, a closure will NEVER capture the variables by default (not like Java inner class which ALWAYS captures this), so, it you use a variable (including self) inside the closure, it is captured.
Also you can manually capture the variables using the [weak self], [weak your_variable_here], [unowned self], [unowned your_variable_here], [self] or [your_variable_here]
If the compiler tells you variable "self" is written to but never read from, it means that you didn't use self inside, so it is completely safe not to use [weak self], because self will NOT be captured, because it is not used.
weak self or unowned self is needed only when your closure captures self, and escapes the function it is passed to, especially if it is saved in a variable.
Refer to Closures in Apple's Official Swift Documentation
No you don't need to. Swift won't do anything with the reference that isn't used so NOT using it does the same as using it.
There are two scenarios when it is correct / appropriate to use [weak self] in closures:
1) The closure references self and is also itself is somehow retained by self, or retained by an object that is in turn retained by self (circular reference / retain cycle).
2) The closure references self, has no form of circular reference with self, but the intent is for the closure NOT to prevent self from being released if there are no other references to self.
In all other cases, there is no need to use [weak self], including cases where the closure has no reference to self (or instance members of self).
I want self to be non-nil and I'm sure it will be, during the blocks execution. So why explicitly specify [unowned self] ?
object.executeBlock {
date = self.lastModified
}
vs
object.executeBlock { [unowned self] in
date = self.lastModified
}
Edit:
Well i'm getting down votes so let's try again. Q: Let’s say I have a problem. That problem is that I would like to prevent a reference cycle. I have two options. I could use [unowned self] or I could use [weak self]. My question therefore, is this: from these two options, why would I choose [unowned self] ? Why not choose [weak self] everytime ?
"The Language Guide claims you should use unowned if the closure and containing object reference each other and will be destroyed at the same time. Presumably that's to avoid the cost of safely nil'ing out a weak reference in an object that's about to dealloc anyway."
http://www.russbishop.net/swift-capture-lists
So [unowned self] makes self an an implicitly unwrapped optional, for the convenience of not unwrapping it yourself, at the risk of a crash if of course it is actually nil.
The only time where you really want to use [unowned self] or [weak self] is when you would create a strong reference cycle. A strong reference cycle is when there is a loop of ownership where objects end up owning each other (maybe through a third party) and therefore they will never be deallocated because they are both ensuring that each other stick around.
Do you have a strong reference cycle there?
I answered this elsewhere. Here's the Cliff notes:
If self could be nil in the closure use [weak self].
If self will never be nil in the closure use [unowned self].
If it's crashing when you use [unowned self] I would guess that self is nil at some point in that closure, which is why you had to go with [weak self] instead.
I really liked the whole section from the manual on using strong, weak, and unowned in closures:
https://developer.apple.com/library/ios/documentation/swift/conceptual/swift_programming_language/AutomaticReferenceCounting.html
Why [unowned self]?
self points to object, object has executeBlock, and executeBlock points back to self, creating a memory cycle.
However when you say [unowned self]: the system will not keep self in memory in order to to make the closure work. it will assume that self is always there when the closure is executed.
If not for some reason, there won't be undefined behavior or anything like that but your app will crash as it is a runtime error.
This is how it was explained by Paul Hegarty, stanford iOS dev teacher.
In a situation where self could conceivably be nil at the time it's used in the closure, you're compelled to use weak semantics (or risk a crash).
In a case where you can reason that self will never be nil, you can choose to specify either: "choose" in the sense that both are correct and will work. Arguably one could be considered "more correct" than the other, in the sense that both semantics satisfy the requirements but one is more specific.
Two reasons you might want to specified unowned instead of self:
Convenience
Documentation
An unowned reference will be more convenient to use because it doesn't need to be unwrapped. It may also be more efficient, since the compiler may not have to produce as much cleanup code for safe deallocation.
In terms of documentation, you're making a kind of assertion about something your program believes to be true. If that assumption (assuming it was valid) is violated, you may like to find out about it in the form of a crash.
Subsequently, this may also make usage of the variable less exhausting: you think about it and document your reasoning that it must always exist up front, and then each time you use it, you don't have to expend further mental energy wondering "what do I do if this isn't here?".
Arguably, using a let binding or guard statement also achieves the latter.
In WWDC 2014 session 403 Intermediate Swift and transcript, there was the following slide
The speaker said in that case, if we don't use [unowned self] there, it will be a memory leak. Does it mean we should always use [unowned self] inside closure?
On line 64 of ViewController.swift of the Swift Weather app, I don't use [unowned self]. But I update the UI by using some #IBOutlets like self.temperature and self.loadingIndicator. It may be OK because all #IBOutlets I defined are weak. But for safety, should we always use [unowned self]?
class TempNotifier {
var onChange: (Int) -> Void = {_ in }
var currentTemp = 72
init() {
onChange = { [unowned self] temp in
self.currentTemp = temp
}
}
}
No, there are definitely times where you would not want to use [unowned self]. Sometimes you want the closure to capture self in order to make sure that it is still around by the time the closure is called.
Example: Making an asynchronous network request
If you are making an asynchronous network request you do want the closure to retain self for when the request finishes. That object may have otherwise been deallocated but you still want to be able to handle the request finishing.
When to use unowned self or weak self
The only time where you really want to use [unowned self] or [weak self] is when you would create a strong reference cycle. A strong reference cycle is when there is a loop of ownership where objects end up owning each other (maybe through a third party) and therefore they will never be deallocated because they are both ensuring that each other stick around.
In the specific case of a closure, you just need to realize that any variable that is referenced inside of it, gets "owned" by the closure. As long as the closure is around, those objects are guaranteed to be around. The only way to stop that ownership, is to do the [unowned self] or [weak self]. So if a class owns a closure, and that closure captures a strong reference to that class, then you have a strong reference cycle between the closure and the class. This also includes if the class owns something that owns the closure.
Specifically in the example from the video
In the example on the slide, TempNotifier owns the closure through the onChange member variable. If they did not declare self as unowned, the closure would also own self creating a strong reference cycle.
Difference between unowned and weak
The difference between unowned and weak is that weak is declared as an Optional while unowned is not. By declaring it weak you get to handle the case that it might be nil inside the closure at some point. If you try to access an unowned variable that happens to be nil, it will crash the whole program. So only use unowned when you are positive that variable will always be around while the closure is around
Update 11/2016
I wrote an article on this extending this answer (looking into SIL to understand what ARC does), check it out here.
Original answer
The previous answers don't really give straightforward rules on when to use one over the other and why, so let me add a few things.
The unowned or weak discussion boils down to a question of lifetime of the variable and the closure that references it.
Scenarios
You can have two possible scenarios:
The closure have the same lifetime of the variable, so the closure will be reachable only until the variable is reachable. The variable and the closure have the same lifetime. In this case you should declare the reference as unowned. A common example is the [unowned self] used in many example of small closures that do something in the context of their parent and that not being referenced anywhere else do not outlive their parents.
The closure lifetime is independent from the one of the variable, the closure could still be referenced when the variable is not reachable anymore. In this case you should declare the reference as weak and verify it's not nil before using it (don't force unwrap). A common example of this is the [weak delegate] you can see in some examples of closure referencing a completely unrelated (lifetime-wise) delegate object.
Actual Usage
So, which will/should you actually use most of the times?
Quoting Joe Groff from twitter:
Unowned is faster and allows for immutability and nonoptionality.
If you don't need weak, don't use it.
You'll find more about unowned* inner workings here.
* Usually also referred to as unowned(safe) to indicate that runtime checks (that lead to a crash for invalid references) are performed before accessing the unowned reference.
I thought I would add some concrete examples specifically for a view controller. Many of the explanations, not just here on Stack Overflow, are really good, but I work better with real world examples (#drewag had a good start on this):
If you have a closure to handle a response from a network requests use weak, because they are long lived. The view controller could close before
the request completes so self no longer points to a valid object when the closure is called.
If you have closure that handles an event on a button. This can be unowned because as soon as the view controller goes away, the button and any other items it may be referencing from self goes away at the same time. The closure block will also go away at the same time.
class MyViewController: UIViewController {
#IBOutlet weak var myButton: UIButton!
let networkManager = NetworkManager()
let buttonPressClosure: () -> Void // closure must be held in this class.
override func viewDidLoad() {
// use unowned here
buttonPressClosure = { [unowned self] in
self.changeDisplayViewMode() // won't happen after vc closes.
}
// use weak here
networkManager.fetch(query: query) { [weak self] (results, error) in
self?.updateUI() // could be called any time after vc closes
}
}
#IBAction func buttonPress(self: Any) {
buttonPressClosure()
}
// rest of class below.
}
If self could be nil in the closure use [weak self].
If self will never be nil in the closure use [unowned self].
The Apple Swift documentation has a great section with images explaining the difference between using strong, weak, and unowned in closures:
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html
Here is brilliant quotes from Apple Developer Forums described delicious details:
unowned vs unowned(safe) vs unowned(unsafe)
unowned(safe) is a non-owning reference that asserts on access that
the object is still alive. It's sort of like a weak optional reference
that's implicitly unwrapped with x! every time it's accessed.
unowned(unsafe) is like __unsafe_unretained in ARC—it's a non-owning
reference, but there's no runtime check that the object is still alive
on access, so dangling references will reach into garbage memory.
unowned is always a synonym for unowned(safe) currently, but the
intent is that it will be optimized to unowned(unsafe) in -Ofast
builds when runtime checks are disabled.
unowned vs weak
unowned actually uses a much simpler implementation than weak.
Native Swift objects carry two reference counts, and unowned
references bump the unowned reference count instead of the strong
reference count. The object is deinitialized when its strong reference
count reaches zero, but it isn't actually deallocated until the
unowned reference count also hits zero. This causes the memory to be
held onto slightly longer when there are unowned references, but that
isn't usually a problem when unowned is used because the related
objects should have near-equal lifetimes anyway, and it's much simpler
and lower-overhead than the side-table based implementation used for
zeroing weak references.
Update: In modern Swift weak internally uses the same mechanism as unowned does. So this comparison is incorrect because it compares Objective-C weak with Swift unonwed.
Reasons
What is the purpose of keeping the memory alive after owning references reach 0? What happens if code attempts to do something with
the object using an unowned reference after it is deinitialized?
The
memory is kept alive so that its retain counts are still available.
This way, when someone attempts to retain a strong reference to the
unowned object, the runtime can check that the strong reference count
is greater than zero in order to ensure that it is safe to retain the
object.
What happens to owning or unowned references held by the object? Is their lifetime decoupled from the object when it is deinitialized or
is their memory also retained until the object is deallocated after
the last unowned reference is released?
All resources owned by the object are released as soon as the object's
last strong reference is released, and its deinit is run. Unowned
references only keep the memory alive—aside from the header with the
reference counts, its contents is junk.
Excited, huh?
There are some great answers here. But recent changes to how Swift implements weak references should change everyone's weak self vs. unowned self usage decisions. Previously, if you needed the best performance using unowned self was superior to weak self, as long as you could be certain that self would never be nil, because accessing unowned self is much faster than accessing weak self.
But Mike Ash has documented how Swift has updated the implementation of weak vars to use side-tables and how this substantially improves weak self performance.
https://mikeash.com/pyblog/friday-qa-2017-09-22-swift-4-weak-references.html
Now that there isn't a significant performance penalty to weak self, I believe we should default to using it going forward. The benefit of weak self is that it's an optional, which makes it far easier to write more correct code, it's basically the reason Swift is such a great language. You may think you know which situations are safe for the use of unowned self, but my experience reviewing lots of other developers code is, most don't. I've fixed lots of crashes where unowned self was deallocated, usually in situations where a background thread completes after a controller is deallocated.
Bugs and crashes are the most time-consuming, painful and expensive parts of programming. Do your best to write correct code and avoid them. I recommend making it a rule to never force unwrap optionals and never use unowned self instead of weak self. You won't lose anything missing the times force unwrapping and unowned self actually are safe. But you'll gain a lot from eliminating hard to find and debug crashes and bugs.
According to Apple-doc
Weak references are always of an optional type, and automatically
become nil when the instance they reference is deallocated.
If the captured reference will never become nil, it should always be captured as an unowned reference, rather than a weak reference
Example -
// if my response can nil use [weak self]
resource.request().onComplete { [weak self] response in
guard let strongSelf = self else {
return
}
let model = strongSelf.updateModel(response)
strongSelf.updateUI(model)
}
// Only use [unowned self] unowned if guarantees that response never nil
resource.request().onComplete { [unowned self] response in
let model = self.updateModel(response)
self.updateUI(model)
}
unowned is similar to weak they don't a retained object from being destroyed, but weak variables turned to nil when the object its a reference to no longer exists, which we can handle with the normal checking of nils, unowned will just become garbage, you can't tell they are no longer garbage and using them will crash. The problem with weak is if an object has references to it by weak variables, when its destroyed, it has to go through every reference to it and set that variable to nil, this clearly is going to be expensive, using unowned instead is going just crash and finding this kind of bug is going to be difficult. One place to use unowned is if you are creating some carefully contained datatype, which has a clear interface, and its internals are not directly accessible, for you implementation it may be useful to have lots of circular references but that are self contained, you can used unowned references to let you break those circular references, with out the expense of weak variables, for example you may have a node tree, and each node needs has to have a reference to its parent, deleting a node is going to delete all its children, so there is no point of all the children having to have all there parent references set to nil.
If none of the above makes sense:
tl;dr
Just like an implicitly unwrapped optional, If you can guarantee
that the reference will not be nil at its point of use, use unowned.
If not, then you should be using weak.
Explanation:
I retrieved the following below at: weak unowned link. From what I gathered, unowned self can't be nil but weak self can be, and unowned self can lead to dangling pointers...something infamous in Objective-C. Hope it helps
"UNOWNED Weak and unowned references behave similarly but are NOT the same."
Unowned references, like weak references, do not increase the retain count of the object being referred. However, in Swift, an unowned reference has the added benefit of not being an Optional. This makes them easier to manage rather than resorting to using optional binding. This is not unlike Implicitly Unwrapped Optionals . In addition, unowned references are non-zeroing. This means that when the object is deallocated, it does not zero out the pointer. This means that use of unowned references can, in some cases, lead to dangling pointers. For you nerds out there that remember the Objective-C days like I do, unowned references map to unsafe_unretained references.
This is where it gets a little confusing.
Weak and unowned references both do not increase retain counts.
They can both be used to break retain cycles. So when do we use them?!
According to Apple's docs:
“Use a weak reference whenever it is valid for that reference to become nil at some point during its lifetime. Conversely, use an unowned reference when you know that the reference will never be nil once it has been set during initialisation.”
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "AnotherViewController")
self.navigationController?.pushViewController(controller, animated: true)
}
}
import UIKit
class AnotherViewController: UIViewController {
var name : String!
deinit {
print("Deint AnotherViewController")
}
override func viewDidLoad() {
super.viewDidLoad()
print(CFGetRetainCount(self))
/*
When you test please comment out or vice versa
*/
// // Should not use unowned here. Because unowned is used where not deallocated. or gurranted object alive. If you immediate click back button app will crash here. Though there will no retain cycles
// clouser(string: "") { [unowned self] (boolValue) in
// self.name = "some"
// }
//
//
// // There will be a retain cycle. because viewcontroller has a strong refference to this clouser and as well as clouser (self.name) has a strong refferennce to the viewcontroller. Deint AnotherViewController will not print
// clouser(string: "") { (boolValue) in
// self.name = "some"
// }
//
//
// // no retain cycle here. because viewcontroller has a strong refference to this clouser. But clouser (self.name) has a weak refferennce to the viewcontroller. Deint AnotherViewController will print. As we forcefully made viewcontroller weak so its now optional type. migh be nil. and we added a ? (self?)
//
// clouser(string: "") { [weak self] (boolValue) in
// self?.name = "some"
// }
// no retain cycle here. because viewcontroller has a strong refference to this clouser. But clouser nos refference to the viewcontroller. Deint AnotherViewController will print. As we forcefully made viewcontroller weak so its now optional type. migh be nil. and we added a ? (self?)
clouser(string: "") { (boolValue) in
print("some")
print(CFGetRetainCount(self))
}
}
func clouser(string: String, completion: #escaping (Bool) -> ()) {
// some heavy task
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
completion(true)
}
}
}
If you do not sure about [unowned self] then use [weak self]
You have references that you don’t want to be strong references, in order to avoid circular references. So at some point when the last strong reference to an object gets removed, the object itself gets removed.
What happens to other non-strong references? Obviously they don’t refer to that object anymore, which is problematic. There are two kinds of ways to handle this:
Weak reference. When the last strong reference to an object goes away, all weak references are set to nil, so a developer can check if the referenced object is there anymore. Quite obviously a weak reference must be an optional, otherwise it couldn’t be set to nil. The strategy to use a weak reference: You write “if let ref = weakref”. Either the reference was still there, and since you just assigned it to a strong reference, it will remain until the end of the “if let”. If you don’t do it this way then you may access the same weak reference twice, and it may be (unexpectedly) not nil on the first access, but nil on the second.
You create an unowned reference. If the object goes away, nobody will tell you. It will look as if you have a reference when to the referred object has gone away. You must only use this if you are 100% sure that the referenced object cannot go away early.
Use unowned if you have measured that it is faster, and when you are 100% that you don’t use the rubbish when the object is gone.