Блок сохранения циклов в Swift?
Традиционно в Objc мы выполняем функцию slo wSelf, чтобы предотвратить дополнительное сохранение количества блоков.
Как Swift внутренне управляет сохранением циклов, которые происходят в блоках для Objc?
3 ответа
Чтобы блок не содержал сильную ссылку на объект, вы должны определить список захвата для блока.
Синтаксис выражения замыкания определяется следующим образом:
{ ( /*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 в соответствующем разделе документации.
Вы должны обратить особое внимание на разницу между weak
а также unowned
, В вашей реализации было бы безопаснее использовать weak
потому что используя unowned
предполагает, что объект никогда не будет нулевым. Это может привести к сбою вашего приложения, если объект был фактически освобожден перед использованием в вашем закрытии.
С помощью weak
как тип ссылки, вы должны развернуть с ?
, следующее:
var myClosure = {
[weak self] in
print(self?.description)
}
Единственное, что меня оттолкнуло со списками перехвата, это когда использовался слабый против неизвестного.
Книга разогнала его до следующих правил:
Если "я" может быть нулевым в замыкании, используйте "слабое я".
Если self никогда не будет нулевым в закрытии, используйте [unowned self].
Более подробное объяснение см. В разделе " Слабые и неизвестные ссылки" в книге "Язык программирования Swift".
Как описано выше, есть 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()
}