Self Refrence Inside Swift Closure Return Nil Some Time

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.

  1. 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()
    }
  2. 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.

  3. 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



Leave a reply



Submit