Блок сохранения циклов в 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()             
}
Другие вопросы по тегам