2017-01-05 2 views
2

Я знаю, что closure может создать retain cycles, если ему присвоено свойство класса и свойства экземпляра класса, используемые внутри замыкания. НоБыстрое управление памятью при передаче замыкания как параметра в singleton

1) Что относительно закрытия не присваивается свойству класса, а передается как параметр методу класса singleton?

2) Как управлять памятью в этом случае?

В способе мой контроллер (UIViewController) У меня есть что-то вроде:

MySingleton.classMethod(parameters ..., completion: {() -> Void in 
    /** 
    doing stuff here 
    */ 
}) 

ответ

4

Если Вы не назначая замыкание на имущество, а просто передав его функции Вам необходимо рассмотреть, если закрытие будет ускользающим или noescape. В Swift 3 по умолчанию все замыкания, переданные в функции, не экранируются.

Вот немного больше информации об этой материи:

«noescape» - пропущенное закрытие вызывается до возвращения функции

«побег» - Если замыкание передается в качестве аргумента к функции, и она вызывается после возвращения функции, закрытие экранируется.

Простое объяснение: нам нужно пометить замыкание как экранирование, когда мы передадим его функции, и закрытие будет вызвано после возвращения этой функции.

Общее правило - это когда закрытие ускользает. Для предотвращения циклов удержания вам необходимо использовать список захвата.

Пример

let closure = { [weak someVariable] (name: Type) -> Void in 
.... 
// code 
} 

Дополнительная информация:

Одна странная вещь, что дополнительные закрытия рассматриваются как избежать. И когда мы явно добавляем ключевое слово escaping, существует ошибка компиляции - атрибут escaping применяется только к типам функций.

См. Ниже ссылки для получения дополнительной информации.

https://bugs.swift.org/browse/SR-2053

https://stackoverflow.com/a/39619298/5388473

https://stackoverflow.com/a/39846519/5388473

Update
Идея использования слабой или бесхозный в списках захвата от вылетающих замыканий является то, что в основном мы не знаем, что будет происходить с пройденное экранирующее замыкание, оно может быть вызвано через некоторое время из другой функции или может быть сохранено в каком-либо объекте, что может привести к сильному циклу удержания.

слабого против бесхозного против сильного захвата

Для получения более подробной информации посетите Apple ARC docs.

От компании Apple документы:

Swift предлагает два пути решения сильных опорных циклов, когда вы работы со свойствами типа класса: слабые ссылки и ссылки не имеющих владельца.

Слабые и неопубликованные ссылки позволяют одному экземпляру в эталонном цикле ссылаться на другой экземпляр, не удерживая его. Экземпляры могут ссылаться друг на друга без создания сильного эталонного цикла.

Используйте слабую ссылку, если другой экземпляр имеет более короткий срок службы , то есть когда другой экземпляр может быть освобожден первым. Используйте неопубликованную ссылку, если другой экземпляр имеет тот же срок службы или более длительный срок службы.

Имейте в виду, что слабый подход добавит плиту котла к коду и будет немного медленнее, потому что ARC добавит код для установки слабых переменных на нуль при их освобождении. Хорошей практикой является следовать правилам, изложенным выше, при выборе слабых или неназванных.

+1

Если я - ссылка на синглтон, то использование слабых здесь не является строго необходимым (хотя, вероятно, все же хорошей практикой), поскольку синглтон никогда не освобождается, и поэтому сильная ссылка на него в закрытии не имеет значения. Блок будет существовать только до тех пор, пока есть ссылка на него. С другой стороны, если self относится к внешнему классу (а не к singleton), а используется слабый, то внешний класс освобождается в соответствии с обычными правилами дуги. Если self не является слабым, класс будет сохранен до тех пор, пока блок не будет выпущен. –

+0

Извините, что я - только пример, я переименую его в someVariable. –

+0

Обновлен ответ с дополнительной информацией об ошибке компиляции опционального закрытия. –

Смежные вопросы