Изучение программирования на Swift: готово ли оно к прайм-тайму?

Опубликовано: 2022-03-11

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

С момента его запуска многие разработчики iOS задавались вопросом, стоит ли, как и когда переходить с Objective-C на Swift. Конечно, ответ на этот вопрос будет разным для каждой команды и каждого проекта.

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

Программирование на Swift может быть готово или не готово к прайм-тайму — вы уже изучили язык Swift?

Но сначала давайте повернем немного время вспять…

До Swift: вы будете использовать Objective-C, и он вам понравится…

Это был 2010 год. iPhone еще не исполнилось 3 лет, а возможность писать нативные приложения для iPhone появилась всего около 2 лет. 8 апреля того же года Apple анонсировала версию iPhone OS. Операционная система iPhone (это было до того, как она сменила название на iOS) включала в себя такие дразнящие новые функции, как многозадачность, быстрое переключение между приложениями и фоновые службы. Понятно, что разработчики iPhone стремились заполучить новый SDK и начать экспериментировать со всеми этими захватывающими новыми функциями.

Но iPhone OS 4 SDK содержал неожиданную бомбу. Эта бомба была не в программном обеспечении, а в соглашении об использовании. В iPhone OS 4 SDK раздел 3.3.1 Соглашения с разработчиком был обновлен, чтобы включить следующую тревожную формулировку:

Приложения должны быть изначально написаны на Objective-C, C, C++… и только код, написанный на C, C++ и Objective-C, может компилироваться и напрямую связываться с документированными API.
– Раздел 3.3.1 Соглашения с разработчиком iPhone OS 4 SDK.

Излишне говорить, что это новое ограничение застало многих разработчиков врасплох. Официальной причиной изменения, названной самим Стивом Джобсом, было предотвращение использования кроссплатформенных инструментов, таких как недавно анонсированный Flash CS5. Джобс сказал, что «промежуточные уровни между платформой и разработчиком в конечном итоге создают [sic] нестандартные приложения». Но тот факт, что подход Apple к борьбе с этими «промежуточными уровнями» заключался в ограничении того, какие языки программирования можно было использовать для написания приложений для iPhone, раскрывал кое-что еще о мышлении Apple: Objective-C должен быть достаточно хорош для всех.

Можно простить согласие с этим утверждением, поскольку Objective-C два года подряд получал награду Tiobe Index «Язык программирования года». Но реальность такова, что популярность Objective-C была функцией растущей экосистемы приложений, а не наоборот. Еще в 2010 году многие люди уже были недовольны Objective-C, и в результате уже появлялись альтернативные способы написания приложений для iPhone на других языках программирования.

В конце концов, под давлением сообщества разработчиков Apple всего пять месяцев спустя отменила эти изменения в разделе 3.3.1 Соглашения с разработчиком SDK. Тем не менее, сообщение было ясным: если вы хотите писать приложения для iPhone, вам, вероятно, следует использовать Objective-C.

… а может и нет. Введите новый язык iOS Swift.

Перенесемся на 4 года вперед с того инцидента до июня 2014 года, когда Apple представила разработчикам свой новый язык Swift. Если за 4 года до этого сообщение заключалось в том, что Apple полностью удовлетворена Objective-C, то сообщение, отправленное представлением Swift, заключалось в том, что Apple наконец-то готова признать правду. Objective-C не обязательно лучший язык для написания мобильных приложений.

Много было сказано о том, что Swift является более «современным» языком, чем Objective-C. Если вам интересно, как изучить язык программирования Swift, вы можете ознакомиться с руководством по переходу с Objective-C на Swift.

Однако вы должны заметить, что между языками Objective-C и Swift есть два важных различия:

  1. Swift не является строгой надстройкой языка C.
  2. Swift имеет статический, а не динамический тип.

Не являясь строгим надмножеством C, Swift может свободно использовать синтаксические конструкции, которые в противном случае были бы запрещены. Это позволяет, например, реализовать собственные операторы в Swift.

Статическая типизация означает, что Swift может использовать преимущества многих последних достижений в системах типов, впервые появившихся в таких языках, как Haskell.

Несмотря на то, что Swift находился в разработке в течение 4 лет, прежде чем был представлен публике, Swift все еще остается молодым языком программирования, поэтому он имеет ряд предостережений.

Совместимость с Objective-C

iOS имеет общее наследие с OS X, которая, в свою очередь, ведет свою историю от операционной системы NeXTSTEP, впервые выпущенной в 1989 году. NeXTSTEP изначально был написан в основном на Objective-C, и многие из основных библиотек в OS X и iOS восходят к своим корням. путь назад к этим первоначальным реализациям. (Кстати, именно отсюда берется вездесущий префикс «NS», встречающийся в основных классах, таких как NSString .) Хотя Swift теоретически мог бы существовать в отсутствие этих основных библиотек, реальность такова, что любые программы Swift, которые вы можете написать в ближайшем будущем, придется взаимодействовать с Objective-C.

К их чести, разработчики Swift проделали фантастическую работу, сделав взаимодействие с существующими библиотеками Objective-C максимально безболезненным. Однако это не означает, что процесс полностью безболезненный. Apple предоставила полезное руководство, объясняющее, как вызывать код Objective-C из Swift и наоборот, но есть некоторые важные несоответствия импеданса, о которых следует знать.

Возможно, самое очевидное несоответствие относится к файлам заголовков. Objective-C, благодаря своим корням C, по-прежнему требует, чтобы функции были объявлены перед вызовом. При обращении к библиотеке эти объявления будут найдены в файлах заголовков библиотеки. Однако Swift не использует файлы заголовков. Итак, если вы хотите вызывать код Swift из Objective-C, вам сначала нужно создать «связующий заголовок». Хотя концептуально это может показаться не таким уж сложным, на практике это может оказаться довольно сложной задачей.

Другой набор сложностей при взаимодействии между Swift и Objective-C связан с неотъемлемыми различиями в их системах типов. Swift, взяв пример с других современных языков, отказался от концепции nil . На его месте находятся необязательные типы Swift. Например, метод, который открывает файл, только если он уже существует, будет иметь возвращаемый тип File? (вместо просто File ) в Swift. Отслеживая все места, где типы являются необязательными, компилятор Swift может эффективно предотвратить возникновение ужасной «Ошибки нулевого указателя». Это, конечно, если вы не вызываете Objective-C. Поскольку Objective-C не дает таких гарантий относительно того, что не будет возвращено nil , Swift имеет специальную категорию типов, называемых неявно развернутыми необязательными опциями , которые используются при вызове кода Objective-C. Эти типы можно рассматривать как необязательные в языке Swift вместе со всеми сопутствующими накладными расходами, необходимыми для проверки существования. В качестве альтернативы их можно использовать так же, как и любой необязательный тип, но если Objective-C вернет nil , вы получите ошибку времени выполнения, поэтому вы потеряете некоторые гарантии безопасности Swift во время компиляции.

Наконец, чуть более тонкое несоответствие, которое следует учитывать при программировании между Swift и Objective-C, связано с тем, как объекты и классы создаются скрыто в этих двух языках. Objective-C, благодаря своей динамической природе, использует динамическую диспетчеризацию для вызова методов объектов (через objc_msgSend ). Swift, безусловно, может использовать динамическую диспетчеризацию, но, поскольку он статически типизирован, он также имеет возможность использовать vtable для хранения указателей функций для каждого метода. Какой из этих двух механизмов использует Swift, зависит от нескольких факторов. Объекты Plane Old Swift будут использовать механизм vtable , если класс или методы внутри класса не аннотированы с использованием @objc Swift. Классы Swift, которые наследуются от классов Objective-C, будут использовать динамическую диспетчеризацию для унаследованных методов, но не для каких-либо новых методов, представленных подклассом (хотя, опять же, вы можете принудительно использовать динамическую диспетчеризацию с помощью атрибута @objc ). Несмотря на это, код Swift всегда сможет работать с классами Swift, но код Objective-C может использовать только объекты и методы Swift, которые были должным образом аннотированы.

Быстрее, чем Objective-C?

Когда Apple представила свой запуск, одним из преимуществ Swift, которое было особо подчеркнуто, была его скорость. Это понятно, если учесть, что одной из причин нежелания Apple переходить с Objective-C на язык более высокого уровня было то, что Objective-C, по сути являющийся расширением C, был способен создавать гораздо более быстрые и эффективные программы. чем что-то вроде Python или Ruby. Тем не менее, Objective-C не является ракетой, когда дело доходит до абсолютной производительности, и многое из этого можно отнести к динамической типизации. Таким образом, с Swift, использующим статическую систему типов, можно было бы ожидать, что Swift должен быть как минимум таким же быстрым или даже быстрее, чем Objective-C.

Конечно, как говорится, «есть три вида лжи: ложь, наглая ложь и ориентиры». (Или что-то в этом роде…) Конечно, есть множество причин, по которым язык Swift может работать быстрее. К сожалению, кажется, что то, как Swift использует технику Apple ARC (автоматический подсчет ссылок) для управления памятью, иногда приводит к тому, что компилятор Swift генерирует значительно более медленные программы, особенно с более низкими настройками оптимизации (например, те, которые вы могли бы использовать во время разработки). Хорошая новость заключается в том, что улучшения в Swift постоянно решают эту проблему, и поэтому вполне вероятно, что в ближайшем будущем Swift будет генерировать исполняемые файлы, по крайней мере, так же быстро или даже быстрее, чем Objective-C.

Однако есть еще одно предостережение относительно скорости Swift. Весь смысл Swift в том, что разработчики не будут писать тот же код, что и на Objective-C. Что это значит для производительности? Ну, конечно, это означает, что сравнение производительности между Swift и Objective-C более сложно, чем могут показать простые тесты. Это также означает, что сравнение абсолютной производительности сгенерированных исполняемых файлов во время выполнения показывает только половину истории.

Всем нужны быстрые программы, но часто скорость разработки не менее важна, если не важнее. Язык, который является более выразительным, способным выполнять больше работы с меньшим количеством строк кода, может быть огромным преимуществом в этом отношении. С другой стороны, при работе на скомпилированном языке, где цикл редактирования-компиляции-запуска-отладки занимает большую часть дня программиста, медленный компилятор может серьезно снизить производительность. Хотя доказательства в основном анекдотичны, кажется, что компилятор Swift в настоящее время достаточно медленный, чтобы раздражать, особенно при работе с кодом, использующим продвинутую систему типов Swift. Одна группа даже обнаружила, что скорость компиляции достаточно проблематична, чтобы побудить вернуться к Objective-C.

Компилятор

Говоря о компиляторе Swift, он сам по себе является источником еще большего количества предостережений при рассмотрении вопроса о переходе на новый язык Swift. Помимо скорости компиляции, поскольку Swift появился из небольшой группы разработчиков, работающих с ним в Apple, и был запущен в массы, компилятор начал давать трещины под нагрузкой. Существует даже целый репозиторий GitHub, посвященный сбору примеров кода, которые могут привести к сбою компилятора Swift.

Также возникает вопрос, как изменится компилятор Swift. Другой проект на GitHub собирает предположения и анализ от сообщества о том, какие изменения могут быть в магазине для Swift. Например, пользовательские операторы могут сильно нагружать синтаксический анализатор. Первоначально пользовательские операторы в Swift не могли использовать символ вопросительного знака (?). Хотя это было исправлено в последней версии Swift, запросы продолжают поступать от растущего сообщества разработчиков Swift для еще большей гибкости в том, что можно считать допустимым пользовательским оператором.

Каждый раз, когда вы слышите, что синтаксический анализатор языка находится в постоянном движении, вы должны задуматься. Синтаксический анализатор языка — это сердце и душа языка программирования. Прежде чем можно будет применить какую-либо языковую семантику для придания смысла коду, синтаксический анализатор определяет, что является допустимым кодом, а что нет. Обнадеживает то, что Apple пообещала обеспечить определенный уровень совместимости для Swift во время выполнения. Однако это не обязательно гарантирует, что код Swift будет работать без перекомпиляции для каждого нового выпуска Xcode и/или iOS. Это также не гарантирует, что вам не нужно будет переписывать части вашего кода Swift, чтобы оставаться совместимым с будущими выпусками Swift. Но опять же, стремление Apple сделать этот процесс максимально безболезненным — это хоть какое-то небольшое утешение.

Сообщество

Некоторые из худших когда-либо созданных языков программирования (которые останутся безымянными) продолжали поддерживаться, хотя здравый смысл говорит, что они должны были быть отправлены на свалку неудачных технологий только благодаря силе соответствующих сообществ. В то же время коллекция действительно хороших языков программирования, которые не прижились из-за отсутствия сообщества, слишком многочисленна, чтобы ее можно было сосчитать. Сильные сообщества создают учебные пособия, отвечают на вопросы о Stack Overflow, общаются в Интернете или лично на конференциях, делятся историями, советами и рекомендациями, а также пишут и делятся друг с другом полезными библиотеками. При выборе языка для проекта обязательно следует учитывать сообщество.

К сожалению, у сообщества iOS/Objective-C не лучшая репутация дружелюбия и гостеприимства. Это постепенно меняется, и открытый исходный код играет все более важную роль в разработке Objective-C. Тем не менее, на этом раннем этапе трудно сказать, как сообщество Swift будет выглядеть в будущем. Будет ли он состоять в основном из изолированных разработчиков, работающих только с официальными API Apple и собственными частными коллекциями кода? Или это будет активное сообщество групп, которые делятся советами, рекомендациями и полезными библиотеками?

Другой аспект роли сообщества — это роль самих разработчиков Swift. Общая тенденция в программировании заключается в переходе от проприетарных языков программирования и платформ к решениям с открытым исходным кодом. Разработка с открытым исходным кодом, особенно на уровне языков программирования и сред выполнения, может быть реальным преимуществом. Хотя разработчики Swift неоднократно заявляли, что их намерение состоит в том, чтобы полностью открыть исходный код языка и среды выполнения Swift, этого еще не произошло, поэтому следует соблюдать осторожность.

Тем не менее, разработчики Swift — одни из тех же разработчиков, что и давно работающий проект LLVM. LLVM не является идеальной аналогией, поскольку он начал свою жизнь как открытый проект Университета Иллинойса, Урбана-Шампейн. Но, к их чести, основные разработчики остались очень открытыми и взаимодействующими с сообществом, даже после того, как большинство из них перешли на работу в Apple. Вполне разумно ожидать, что язык Swift будет продолжать развиваться (в основном) в открытом доступе, хотя пока неизвестно, будут ли патчи и предложения от сообщества когда-либо попадать в язык.

Должен ли я изучать Свифт?

Здесь, конечно, нет универсального ответа. Как всегда, выбор правильного инструмента для работы требует глубокого знания всех деталей рассматриваемого проекта. Конечно, на данный момент Objective-C остается «безопасным» выбором для разработки под iOS, но Swift определенно заслуживает внимания.

Однако самое значительное изменение, которое Swift привносит в разработку iOS, заключается в том, что многие разработчики впервые задают себе вопрос: «Какой язык мне следует использовать?» Учитывая историю Apple, Objective-C и платформы iOS, само по себе это изменение довольно интересно, особенно если учесть, что выбор не является бинарным. В то время как Apple четко обозначила свои предпочтения, сообщество разработчиков iOS в целом уже много лет усердно работает, давая еще больше возможных ответов на этот вопрос.