В чем смысл следующего быстрого кода? - PullRequest
0 голосов
/ 29 августа 2018

Может кто-нибудь сказать мне, почему мы используем guard let self = self ??

Я видел этот код, читая о GCD, я не мог понять, что делает эта конкретная строка.

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

    // ...
}

Ответы [ 4 ]

0 голосов
/ 29 августа 2018

self объявляется weak в этом блоке, поэтому имеет тип Optional. Например. если имя вашего класса - MyViewController, тогда тип self в этом блоке - MyViewController?. Причина использования слабых заключается в том, чтобы избежать сохранения циклов. Блок должен выполняться, только если self еще живо. Таким образом, одно решение будет:

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

но нет необходимости называть это strongSelf. Вы также можете назвать это self. Переменная self после блока guard на самом деле является переменной, отличной от self, она просто имеет то же имя.

Итак, значение:

Выполнять этот блок, только если self еще жив. (В противном случае ничего не делать.)

0 голосов
/ 29 августа 2018

Код внутри async {} будет выполняться асинхронно. Функция завершения ({ [weak self] ... }) содержит (сильную по умолчанию) ссылку на объект, вызывающий функцию async.

Поскольку он асинхронный, у вас нет способа узнать а) когда будет выполнен обратный вызов, б) будет ли он выполнен. Это означает, что сильная ссылка на self может вызвать утечку памяти.

Вот почему каждый использует [weak self] для передачи слабой ссылки. Поскольку вызов асинхронный, может случиться так, что, когда обратный вызов будет окончательно выполнен, ARC уже собрал ссылку на self и, таким образом, self будет nil.

Тогда хорошо проверить, существует ли self, до выполнения кода в обратном вызове.

0 голосов
/ 29 августа 2018

Поток создается и добавляется в глобальную очередь, и QOS (качество обслуживания или, можно сказать, приоритет этого потока) инициируется пользователем (средний приоритет), после чего выполняется набор инструкций async

0 голосов
/ 29 августа 2018

Сначала вы создаете блок, который будет выполняться асинхронно

DispatchQueue.global(qos: .userInitiated).async

Затем внутри блока код проверяет, выделен ли self, объект, вызывающий эту функцию,

guard let self = self else {
  return
}

Нам нужно проверить это, потому что self объявлено как weak внутри блока, чтобы избежать цикла сохранения ( Быстрые замыкания, вызывающие сильный цикл сохранения с self ), и его можно освободить до выполнения блока. Эта строка кода проверяет, является ли self! = Nil, и присваивает его себе, в противном случае возвращает.

...