0

Can anyone tell me why we use guard let self = self ??

I have seen this code while reading about GCD, I couldn't figure out what that particular line does.

DispatchQueue.global(qos: .userInitiated).async { [weak self] in
    guard let self = self else {
        return
    }

    // ...
}
Michael
  • 6,451
  • 5
  • 31
  • 53
vijeesh
  • 1,317
  • 1
  • 17
  • 32
  • 1
    You can see this block is capturing self as weak using [weak self], So now the self is optional to use inside the block. so you can use as self? to access anything or use guard let in the beginning and can use as self without ? symbol. – vivekDas Aug 29 '18 at 09:55
  • 2
    Possible duplicate of [How to "strongify" optional self using guard in Swift 2.0](https://stackoverflow.com/questions/32588431/how-to-strongify-optional-self-using-guard-in-swift-2-0) – Cristik Aug 29 '18 at 21:36

4 Answers4

5

First you are creating a block that will be executed asynchronously

DispatchQueue.global(qos: .userInitiated).async

Then inside the block the code checks if self, the object that is calling this function, is still allocated

guard let self = self else {
  return
}

We need to check this because self is declared as weak inside the block to avoid a retain cycle (Swift closures causing strong retain cycle with self) and can be deallocated before the block is executed. That line of code checks if self is != nil, and assign it to self, otherwise it returns.

LorenzOliveto
  • 7,796
  • 1
  • 20
  • 47
3

self is declared weak in this block, so it has an Optional type. E.g. if the name of your class is MyViewController then the type of self in that block is MyViewController?. The reason for the use of weak is to avoid retain cycles. The block should only execute if self is still alive. So one solution would be:

DispatchQueue.global(qos: .userInitiated).async { [weak self] in
    guard let strongSelf = self else {
        return
    }
    strongSelf.makeFoo()
    strongSelf.continueWithBar()
}

but there is no need to call it strongSelf. You can call it self too. The self variable after the guard block is actually a different variable than self, it just has the same name.

So the meaning is:

Execute this block only if self is still alive. (Otherwise, do nothing.)

Michael
  • 6,451
  • 5
  • 31
  • 53
1

The code inside async {} will b executed asynchronously. The completion function ({ [weak self] ... }) contains a (default strong) reference to the object calling the async function.

Since it is asynchronous you don't have a way to know a) when the callback will be executed b) if it will be executed. Meaning that the strong reference to self could cause a memory leak.

That is why one uses [weak self] to pass a weak reference. Since the call is async, it can be that, when the callback is finally executed, the ARC has already collected the reference to self and thus self would be nil.

It is then good to check if self still exists before executing the code in the callback.

regina_fallangi
  • 2,080
  • 2
  • 18
  • 38
0

A thread is being created and added to global queue and has QOS(Quality of service or you can say priority of that thread) user initiated(medium priority) after that you execute set of instructions async

Mohit Arora
  • 102
  • 1
  • 7