self refrence inside swift closure return nil some time
I am able to fix this issue by making strong instance while creating it, in my case this weak variable was making nil to self. Thanks all for providing suggestion for my queries.
Swift weak reference going nil even when self keeps existing
Problem solved. Ok, so I don't know what was going on, but it fixed itself after multiple attempts to debug it. One thing that is still buggy is that the debugger show self
as nil
inside the closure (which added a significant time in the debugging process), but the guard let
block executes successfully and I get a strong reference to the object.
weak self always nil in asynchronous closure Alamofire
Whatever object is that self
refers to has gone by the time the Alamofire's completion request handler gets executed. You need to keep a strong reference to self
somewhere until after the response handler has run. In your first example with the strong self
the closure itself provides the strong reference. In the second example with weak self
nothing does.
What option you choose is dependent on circumstances. Looking at your code, such as it is, you don't keep a reference to the Alamofire request anywhere so you'll probably be OK with the your first option - the object referred to by self
doesn't keep a strong reference to the request either directly or indirectly, so there's no ownership cycle.
Is it the right way using `[weak self]` in swift closure?
Your pattern has race condition. If self
was deallocated at the exact same time as your completion handler closure was executing, it could crash. As a general rule, avoid using the !
forced unwrapping operator if you can.
I’d lean towards the
guard
“early exit” pattern (reducing nested braces, making code easier to read). The standard Swift 4.2 solution is:someTask { [weak self] result in
guard let self = self else { return }
self.xxx = yyy
self.doLongTermWork()
self.finish()
}Before Swift 4.2, which implemented SE-0079, we would have to do something like:
someTask { [weak self] result in
guard let strongSelf = self else { return }
strongSelf.xxx = yyy
strongSelf.doLongTermWork()
strongSelf.finish()
}You can see why we prefer the Swift 4.2 improvement, as this
strongSelf
syntax is inelegant.The other obvious alternative is just:
someTask { [weak self] result in
self?.xxx = yyy
self?.doLongTermWork()
self?.finish()
}Sometimes you need the “weak self - strong self dance” (the first two alternatives), but it would not appear to be the case here. This is likely sufficient.
There are other scenarios/edge cases that one might contemplate, but these are the basic approaches.
Shall we always use [unowned self] inside closure in Swift
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
Swift: should completion closure have error indication when weak self is nil?
It's up to ur purpos.
If u just want stop process without callback, u can do like this.
If u want to distinguish success or fail, u can return by Bool or Error.
func doTheWork(completion:@escaping((_ success:Bool)->Void)) {
process { [weak self] in
guard let self = self else {
completion(false)
return
}
completion(true)
}
}
func printJsonStr(_ jsonUrl:URL,completion:@escaping((_ error:Error?)->Void)) {
do {
let data = try Data(contentsOf: jsonUrl)
} catch {
completion(error)
}
completion(nil)
}
What is the usage of guard let self = self else { return }
Your concern is correct. Because getFollowers
is an async task, user could go back to previous screen while the task is running. In that case, self
could be nil
and the return
is okay.
On the other hand, to make sure there's no problem with completion block of getFollowers
task, self
will be captured as strong
reference, that could cause memory leak even if user already leave that screen.
He uses weak self
to prevent that happens.
Swift, how much of self do closures capture?
class B who is only referenced from class A.
I assume you mean something like this in A
:
var objB: B?
Just before closure Z calls functions from class B, class B gets cleaned out.
Well, there is only one way to clean out B
:
objB = nil
Now when you call B's methods in the closure, you will get an "unexpectedly found nil while unwrapping an optional value".
This is because you only captured self
, which is A
,in the closure. You did not capture B
at all. The instance of B
is retained by the strong reference from A
. Basically, B
is not captured by the closure.
My confusion comes because in closure Z, i can specify [weak self], but I cannot do that for the functions I want to call in class B.
Well, you can capture B
though. Just like this:
[b = self.objB] in ...
You can also make it weak:
[weak b = self.objB] in ...
This way you can also capture B in the closure.
Related Topics
How to Make Swiftui Uiviewrepresentable View Hug Its Content
Why Do I Get "Static Member '...' Cannot Be Used on Instance of Type '...'" Error
Drawing Pixels on the Screen Using Coregraphics in Swift
How to Trim a String in Swift Based on a Character
Unknown Error When Adding an CSSearchableitem to Core Spotlight (Macos)
Having Trouble with Nstimer (Swift)
How to I Turn Off the Ambient Light in Scene Kit (With Swift)
Different Colors for Bars in Barchart Depend on Value
What Does a "Do Statement" Without Catch Block Mean
Swiftui Tabbar: Action for Tapping Tabitem of Currently Selected Tab to Reset View
How to Add Floating Button on Top of the Uitableview
Create a Swift Dictionary Subclass
iOS Charts Remove Decimal from Yvalues
A Swiftier Way to Convert String to Unsafepointer<Xmlchar> in Swift 3 (Libxml2)
Build Realm for Swift 3 & Xcode 8
Xctestcase Optional Instance Variable