Традиционно в Objc мы делаем weakSelf для предотвращения дополнительного количества удержания для блоков.
Как быстро выполнять внутренние циклы сохранения, которые происходят в блоках для Objc?
Традиционно в Objc мы делаем weakSelf для предотвращения дополнительного количества удержания для блоков.
Как быстро выполнять внутренние циклы сохранения, которые происходят в блоках для Objc?
Чтобы блок не содержал значительную ссылку на объект, вы должны определить список захвата для блока.
Синтаксис выражения закрытия определяется следующим образом:
{ ( /*parameters*/ ) -> /*return type*/ in
// statements
}
Но это более подробно описано в документации для включения списка захвата. Это фактически эквивалентно синтаксису выражения, определяемому следующим образом:
{ [ /*reference type*/ /*object*/, ... ] ( /*parameters*/ ) -> /*return type*/ in
// statements
}
... где /*reference type*/
может быть либо weak
, либо unowned
.
Список захвата - это первое, что появляется в закрытии, и оно необязательно. Синтаксис, как показано выше, определяется как одна или несколько пар ссылочного типа, за которыми следует объект; каждая пара разделяется запятой. Например:
[unowned self, weak otherObject]
Полный пример:
var myClosure = {
[unowned self] in
print(self.description)
}
Обратите внимание, что ссылка unowned
не является необязательной, поэтому ее не нужно разворачивать.
Надеюсь, это ответит на ваш вопрос. Вы можете прочитать больше о ARC в Swift в соответствующем разделе documentation.
Вы должны обратить особое внимание на разницу между weak
и unowned
. В вашей реализации может быть безопаснее использовать weak
, поскольку использование unowned
предполагает, что объект никогда не будет равен нулю. Это может привести к сбою вашего приложения, если объект фактически был освобожден до использования в вашем закрытии.
Используя weak
в качестве ссылочного типа, вы должны развернуть с помощью ?
следующим образом:
var myClosure = {
[weak self] in
print(self?.description)
}
Единственное, что отбросило меня с помощью списков захвата, было тогда, когда нужно использовать слабый vs unowned.
Книга переделала эти правила:
Если self может быть nil в использовании замыкания [слабый я].
Если self никогда не будет nil в использовании закрытия [unowned self].
В разделе "Книга быстрого языка программирования" см. раздел "Слабые и неопубликованные ссылки" .
Как описано выше, существует 2 возможности избежать циклов удержания в Swift, и это weak
и unowned
, как описано ниже:
var sampleClosure = { [unowned self] in
self.doSomething()
}
где self
никогда не может быть nil
.
var sampleClosure = { [weak self] in
self?.doSomething()
}
где self
необходимо развернуть с помощью ?
.
Здесь есть важное замечание, если есть больше инструкций, которые используют self и могут делиться результатами и т.д., Возможно правильный способ:
var sampleClosure = { [weak self] in
if let this = self{
this.doSomething()
this.doOtherThings()
}
}
или
var sampleClosure = { [weak self] in
guard let strongSelf = self else{
return
}
strongSelf.doSomething()
strongSelf.doOtherThings()
}