简体   繁体   中英

What is the meaning of following swift code?

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
    }

    // ...
}

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.

self is declared weak in this block, so it has an Optional type. Eg 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.)

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.

正在执行异步指令集之后,正在创建一个线程并将其添加到全局队列中,并具有用户启动的QOS(服务质量或您可以说该线程的优先级)(中等优先级)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM