Короткие ответы
- Компиляторы используют различные процессы для анализа кода. В колледжах есть множество лекций о том, как работают компиляторы. Поэтому довольно сложно дать вам правильный ответ.
- Используйте то, что вам нужно. Довольно сложно оценить, сколько это стоит. @escaping и @ no-escaping имеют разные варианты использования.
- Я не вижу недостатков. Использование слабых - хороший способ предотвратить циклы розничной торговли и утечки памяти.
Объяснение
1: Так как именно работает этот компилятор, я действительно не знаю. Но если вы хотите получить представление о том, как обычно работают компиляторы, прочитайте несколько легких статей, подобных этой one
По моей идее, у компилятора будет лексический анализ, синтаксический анализ и семантический анализ. Таким образом, компилятор определит, нужен ли вам выход или нет.
2: Closures - это стремительная концепция, которая гласит: «Делай вещи, когда дела идут». Для более подробной информации смотрите документацию и здесь
Следующая информация во многом основана на этой статье что-делать-значит-убегать-и-не-спасаться-закрывать-в-быстром
В Swift 1 и 2 закрытия были @escaping по умолчанию. С Swift 3 замыкания @ не выходят.
@ без побега
Когда вы передаете замыкание в аргументах функции, используйте его до того, как тело функции выполнится и вернет компилятор обратно. Когда функция завершается, переданное закрытие выходит из области видимости и больше не существует в памяти.
Проще говоря, это удобная обработка памяти для разработчика, потому что он ни о чем не заботится.
@ escaiping closures
Для @escaping замыканий есть два варианта использования:
Хранение: Когда вам нужно сохранить замыкание в глобальной переменной, выполняется свойство или любое другое хранилище, которое существует в памяти после вызывающей функции, и возвращает компилятор обратно.
Асинхронное выполнение: Когда вы выполняете закрытие асинхронно в очереди отправки, очередь сохранит закрытие в памяти для вас, и может быть использовано в будущем. В этом случае вы не знаете, когда будет выполнено замыкание.
Из документации Apple
Говорят, что замыкание экранирует функцию, когда замыкание передается как
аргумент функции, но вызывается после возврата функции.
[...] вы можете написать @escaping перед типом параметра в
указывают, что закрытию разрешено сбежать.
К вашему сведению: закрывает отметки о том, что операция является асинхронной и не является обязательной в фоновом потоке.
3: я не вижу недостатков в его использовании. Использование слабых - хороший способ предотвратить циклы розничной торговли и утечки памяти. Вы должны игнорировать потенциальные затраты, когда вы получаете стабильное приложение. Но я повторяю: используйте то, что вам нужно. С утечками памяти это сложно, и часто их трудно найти.
См. https://stackoverflow.com/a/34566876/4420355 для действительно хорошего ответа о делегатах и утечках памяти. В этом посте также много других ссылок. Если вы прочитаете их, вы получите хорошее / лучшее понимание того, как будут происходить утечки памяти и как их предотвратить.
И проверьте этот пост тоже, он немного похож на ваш https://stackoverflow.com/a/46245943/4420355
Изменить на 3
спрашивающий:
Полагаю, я не понял это правильно ... так что значит "захватить", как это действительно работает за сценой с точки зрения непризнанного я? как замыкание использовать себя без владения объектом? может быть, этот вопрос должен быть отдельно от stackoverflow
Вдохновленный примером поста Можно ли получить доступ к памяти локальной переменной за пределами ее области видимости?
Вы снимаете номер в отеле. Вы выезжаете на следующее утро, запираете дверь, но «забыли» вернуть свой ключ. Ты украл ключ! Там нет запасного ключа. Так что номер в отеле заперт. Владелец отеля больше не может арендовать этот номер. Сейчас много гостей, которые крадут ключ. Иногда каждая комната на самом деле свободна, но заперта.
С небольшой фантазией арендатор закрывается. Он снимает комнату (создает ссылки на экземпляр комнаты). Он там спит (асинхронная операция). Он должен вернуть свой ключ, но он этого не делает.
В моем понимании замыкание не владеет объектом. Это ссылка между замыканием и свойством экземпляра.
Документация Apple:
Сильный референтный цикл также может произойти, если вы назначите закрытие
свойство экземпляра класса, и тело этого замыкания захватывает
экземпляр. Этот захват может произойти, потому что тело закрытия
обращается к свойству экземпляра, такому как self.someProperty или
потому что замыкание вызывает метод в экземпляре, такой как
self.someMethod (). В любом случае эти доступы приводят к закрытию
«Захватывать» себя, создавая сильный референтный цикл.
Вы можете разрешить этот сильный цикл с помощью weak
или unowned
. По моему мнению, изображения, которые Apple использует для объяснения разницы между weak
и unowned
, действительно хороши: см. Автоматический подсчет ссылок