Swift - @escaping и захватить уточнение списка

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

  1. Как компилятор знает, что я должен добавить @escaping в фоновый поток, и тем самым заставить меня использовать его?
  2. Есть ли плата за использование @escaping? если нет.. почему бы не отметить всегда? Что может пойти не так, если я отмечу закрытие @escaping, даже если оно мне действительно не нужно? Когда я пытался это сделать... в моем коде не было проблем, и результат с или без @escaping остался прежним.
  3. Какова стоимость использования списка захвата [слабая личность] [непризнанная личность]? Я знаю, что он создает копию этого объекта, так что я полагаю, что временно это займет больше памяти, но в конце этого использования эта копия будет удалена из памяти... итак, есть еще недостатки в использовании?

1 ответ

Короткие ответы

  1. Компиляторы используют разные процессы для анализа кода. В колледжах есть множество лекций о том, как работают компиляторы. Поэтому довольно сложно дать вам правильный ответ.
  2. Используйте то, что вам нужно. Довольно сложно оценить, сколько это стоит. @escaping и @no-escaping имеют разные варианты использования.
  3. Я не вижу недостатков. Использование слабых - хороший способ предотвратить циклы розничной торговли и утечки памяти.

объяснение

1: Так как именно работает этот компилятор, я действительно не знаю. Но если вы хотите понять, как обычно работают компиляторы, прочитайте несколько легких статей, подобных этой

По моей идее, у компилятора будет лексический анализ, синтаксический анализ и семантический анализ. Таким образом, компилятор определит, нужен ли вам выход или нет.

2: замыкания - это быстрое понятие: "Делай вещи, когда дела идут". Более подробно смотрите в документации и здесь

Следующая информация во многом основана на этой статье " что делать, значит убегать и не убегать-замыкания-в-быстром"

В Swift 1 и 2 замыкания были @escaping по умолчанию. С Swift 3 замыкания @ не выходят.

@ без побега

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

Проще говоря, это удобная обработка памяти для разработчика, потому что он ни о чем не заботится.

@escaiping закрытия

Для замыканий @escaping есть два варианта использования:

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

Асинхронное выполнение: Когда вы выполняете закрытие асинхронно в очереди отправки, очередь будет держать закрытие в памяти для вас, может быть использовано в будущем. В этом случае вы не знаете, когда будет выполнено замыкание.

Из документации Apple

Говорят, что замыкание экранирует функцию, когда замыкание передается в качестве аргумента функции, но вызывается после ее возврата. [...] вы можете написать @escaping перед типом параметра, чтобы указать, что закрытию разрешено экранировать.

К сведению: закрытие отмечает, что операция является асинхронной и не является обязательной в фоновом потоке.

3: я не вижу недостатков, чтобы использовать это. Использование слабых - хороший способ предотвратить циклы розничной торговли и утечки памяти. Вы должны игнорировать потенциальные затраты, когда вы получаете стабильное приложение. Но я повторяю: используйте то, что вам нужно. С утечками памяти это сложно, и часто их трудно найти.

См. /questions/5064527/kak-sdelat-slabuyu-ssyilku-na-protokol-v-chistom-swift-bez-objc/5064534#5064534 для действительно хорошего ответа о делегатах и ​​утечках памяти. В этом посте также много других ссылок. Если вы прочитаете их, вы получите хорошее / лучшее понимание того, как будут происходить утечки памяти и как их предотвратить.

И проверьте этот пост тоже, он немного похож на ваш /questions/19100189/swift-escaping-i-obrabotchik-zaversheniya/19100205#19100205

Изменить на 3

спрашивающий:

Я предполагаю, что я не понял это правильно... так, что означает "захват", как это действительно работает за сценой с точки зрения непризнанного я? как замыкание использовать себя без владения объектом? может быть, этот вопрос должен быть отдельным от stackru

Вдохновленный примером поста Можно ли получить доступ к памяти локальной переменной вне ее области?

Вы снимаете номер в отеле. Вы выезжаете на следующее утро, запираете дверь, но "забыли" вернуть свой ключ. Ты крадешь ключ! Там нет запасного ключа. Так что номер в отеле заперт. Владелец отеля больше не может арендовать этот номер. Сейчас много гостей, которые крадут ключ. Иногда каждая комната на самом деле свободна, но заперта.

С небольшой фантазией арендатор закрывается. Он снимает комнату (создает ссылки на экземпляр комнаты). Он там спит (асинхронная операция). Он должен вернуть свой ключ, но он этого не делает.

В моем понимании закрытие не владеет объектом. Это ссылка между замыканием и свойством экземпляра.

Документация Apple:

Цикл строгой ссылки также может произойти, если вы назначаете замыкание свойству экземпляра класса, а тело этого замыкания захватывает экземпляр. Этот захват может произойти, потому что тело замыкания обращается к свойству экземпляра, например self.someProperty, или потому что закрытие вызывает метод экземпляра, например self.someMethod(). В любом случае эти обращения заставляют замыкание "захватывать" себя, создавая сильный референтный цикл.

Вы можете решить этот сильный цикл с weak или же unowned, В моем opionen изображения, которые Apple использует, чтобы объяснить разницу между weak а также unowned действительно хороши: см. Автоматический подсчет ссылок

Другие вопросы по тегам