В этой статье я надеюсь объяснить, почему мы можем использовать атрибут @escaping, и объяснить разницу между значением по умолчанию @noescape.

Если вы использовали Swift 2, возможно, вы использовали атрибут @noescape и, возможно, знаете, что позже он стал устаревшим в Swift 3 с введением атрибута @escaping. Чтобы понять, почему, давайте посмотрим, что мы подразумеваем под @escaping.

Избегание замыканий

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

Давайте посмотрим на пример.

Как вы можете видеть, компилятор здесь ошибается, потому что блок завершения, который мы передаем в качестве параметра, экранируется из тела функции, поскольку он вызывается в блоке URLSessionDataTask. В Swift 2 приведенный выше код будет компилироваться, потому что по умолчанию установлено значение @escaping, но для Swift 3 и выше значение по умолчанию - @nonescape. Фактически, атрибут @nonescape устарел, вы больше не можете использовать этот атрибут.

Чтобы исправить указанную выше проблему, нам просто нужно пометить блок завершения как @escaping, как показано ниже.

Заключение

В заключение отметим, что пометка замыканий как @nonescape по умолчанию дает несколько преимуществ. Наиболее очевидные преимущества - это производительность и возможность компилятора оптимизировать ваш код. Это также означает, что вы можете обойтись без слабых ссылок на self в закрытии @nonescape, потому что оно вызывается до возврата из функции.

Надеюсь, эта статья была полезной, и если я что-то пропустил, дайте мне знать 🙂