Vladimir Buikliskii

Vladimir Buikliskii 

iOS разработчик, автор ТГ канала @swiftynew

93subscribers

27posts

goals4
13 of 30 paid subscribers
Наберу 30 подписчиков и начну разбирать алгоритмы
1 of 3
$3.64 of $365 raised
Сбор на верстку и выпуск книги "100 вопросов для iOS-разработчика". Средства пойдут на профессиональную верстку книги и ее последующий выпуск.

Почему опциональные замыкания в Swift являются escaping

10 июня 2018
https://www.jessesquires.com/blog/2018/06/10/why-optional-swift-closures-are-escaping/
В недавнем эпизоде подкаста мы с JP обсудили неявное escaping замыканий в Swift. По мере развития Swift поведение параметров замыканий в функциях по умолчанию изменилось. До Swift 3 параметры замыканий по умолчанию были escaping. После принятия SE-0103 поведение по умолчанию изменилось на non-escaping.
В Swift 3, чтобы отказаться от поведения по умолчанию, вы могли аннотировать параметр функции с помощью @noescape. Теперь, когда это поведение стало стандартным, вам нужно указать @escaping, чтобы замыкание стало escaping. Грег Хео (Greg Heo) предоставляет отличное объяснение на Swift Unboxed.
В любом случае, наш эпизод был сосредоточен на недавно обнаруженной проблеме в компиляторе Swift, где замыкание с модификатором no-escape, переданное из Swift, могло стать escaping в Objective-C. Дуг Грегор (Doug Gregor) подробно объяснил проблему на форумах Swift. Во время нашего обсуждения в шоу была еще одна часть истории об "escaping замыканиях", в которой мы с JP были не уверены.
Оставив в стороне все эти правила и изменения, параметры опциональных замыканий не могут быть аннотированы, потому что они всегда неявно являются escaping. Но почему?
В Твиттере Дэвид Харт (David Hart) объяснил:
Нет смысла добавлять аннотации escaping к опциональным замыканиям, потому что они не являются типами функций: по сути, это enum (Optional), содержащий функцию, так же как вы бы хранили замыкание в любом типе. Оно неявно является escaping, потому что находится во владении другого типа.
Теперь мне это кажется таким очевидным, но, честно говоря, я не понимал, почему к опциональным замыканиям относятся иначе. Optionals — это всего лишь enum с двумя случаями. Как и любой другой тип, который содержит замыкание, это замыкание по определению является escaping. Таким образом, опциональное замыкание не сильно отличается от структуры, которая имеет свойство-замыкание:
typealias Handler = () -> Void
struct Closure {
    let handler: Handler
}
Более того, нет смысла аннотировать нефункциональные типы как @escaping. Конечно, это довольно легко проверить самостоятельно:
func performWorkOptional(handler: Handler?) {
      print(type(of: handler))
}
performWorkOptional { /* ... */ }
// выводит: Optional<() -> ()>

А для случая без опционала:
func performWork(handler: @escaping Handler) {
      print(type(of: handler))
}
performWork { /* ... */ }
// выводит: () -> ()
Subscription levels3

Базовый уровень

$1.21 per month
Подписавшись на базовый уровень, вы получите:
1) Доступ к переводу популярных статей на тему iOS-разработки.

Стандартный уровень

$4.8 per month
Подписавшись на стандартный уровень, вы получите:
1) Доступ к переводу официальной документации Swift(Notion).
2) Доступ к переводу популярных статей на тему iOS-разработки.
3) Подробный список библиотек с инструкциями по их настройке для удобной работы с проектами(Notion -  https://www.notion.so/).
4) Вопросы и ответы из реальных собеседований.
5) Ранний доступ к онлайн-версии книги "100 вопросов для iOS-разработчика" до официального релиза.(Сечйас  доступен черновик)
6) Доступ к закрытому чату.

Продвинутый уровень(Менторство)

$61 per month
Подписавшись на продвинутый уровень, вы получите:
1. Все материалы и преимущества стандартного уровня.
2.  4 часа личных консультаций в месяц (онлайн-созвон или разбор кода/проектов).
Go up