Введение

Всем привет! Меня зовут Сергей, и я работаю разработчиком мобильных приложений. Также мы с ребятами развиваем международное комьюнити Coffee&Code, а сам я частый гость на встречах в Санкт-Петербурге.

Хочу поговорить о теме, которая волнует многих разработчиков: использование старых технологий в iOS-разработке, таких как Objective-C. Тут возникает очень насущный вопрос, являются ли он легаси?

Насыплю немного терминов на размышление

Легаси – это не просто старый код, написанный на устаревших языках или с использованием старых технологий, это любой код, который сложно поддерживать и развивать. Это может быть и относительно новый код, если он плохо структурирован, недостаточно документирован или содержит множество технического долга.

Технический долг – это метафора, используемая для описания последствий принятия неоптимальных решений в программировании. Эти решения могут быть вызваны разными причинами: нехваткой времени, ресурсов или знаний. Например, чтобы быстрее выпустить продукт, разработчики могут сознательно использовать менее оптимальные решения, что создает долг, который в будущем нужно будет погасить, тратя время на исправление или переработку кода.

Технический долг может проявляться в следующих формах

  1. Проблемы с кодом - Отсутствие общих стандартов, использование неочевидных решений и копипаста. Это затрудняет его дальнейшее сопровождение и усложняет понимание другим разработчикам

  2. Неподходящая архитектура - Проектирование системы без учета масштабируемости и гибкости, что затрудняет внесение изменений

  3. Отсутствие документации и тестов - Без достаточной документации и тестов код становится менее понятным и более подверженным ошибкам при изменениях

Технический долг накапливается, если своевременно не заниматься его устранением, что в конечном итоге приводит к увеличению затрат на поддержание и развитие проекта, а также на деливери фичей.

Ближе к делу!

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

Проблематика

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

Цель

Разобраться в старых инструментах, познакомиться с хорошими практиками, показать различия инструментов и самое главное их сходство. Посмотреть примеры кода. Заполнить пробелы в знаниях. После прочтения дать тебе возможность смело заявить, что язык не принципиален, и что ты, как крутой iOS инженер, сможешь справиться с задачей при любых условиях.

Разберу примеры кода на старых и свежих инструментах, дам несколько мыслей для обдумывания и применения различных технологий и попробую избавить вас от страха перед старьём.

Структура

  1. Статистика использования языков

  2.  Историческая справка

  3. Сильные и слабые стороны

  4. Совместимость

  5. Миграция

  6. Заключение

  7. Рекомендуемые материалы для расширения кругозора

1 - Статистика использования языков

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

Мы рассмотрим данные, которые помогут оценить, насколько востребованы старые и новые инструменты в сообществе разработчиков, и в какой степени каждый из них используется в реальных проектах. Это понимание поможет нам осознать актуальность каждого языка и сделать первый шаг к решению нашей проблемы и избавиться от страха перед Objective-C.

Популярность языков программирования

По данным TIOBE Index за июнь 2024 года, Swift занимает 12-е место среди самых популярных языков программирования, тогда как Objective-C находится на 37-м месте. Это показывает, что Swift становится более предпочтительным выбором для разработчиков, но Objective-C всё еще имеет значительное количество пользователей.

Язык

Место в рейтинге

C++

2

С

3

Swift

12

Objective-C

37

Использование в разработке

Согласно опросу всех разработчиков Stack Overflow Developer Survey 2023, около 4% используют Swift, тогда как около 2% продолжают использовать Objective-C. Это отражает предпочтение современного языка, но также указывает на значительное присутствие Objective-C в старых кодовых базах и проектах.

Язык

Процент использования

C++

22.42%

С

19.34%

Swift

4.65%

Objective-C

2.31%

Поддержка в проектах с открытым исходным кодом

На GitHub можно увидеть, что количество репозиториев со Swift значительно превышает количество репозиториев с Objective-С. В 2024 году количество активных репозиториев на Swift примерно в два раза больше, чем на Objective-C.

Язык

Количество репозиториев

C++

3.6м

С

2.4м

Swift

Objective-C

512к

Использование Swift и Objective-C компанией Apple в iOS 17

В статье Alexandre Colucci Apple’s use of Swift and SwiftUI in iOS 17  он выделил использование языков в iOS 17 на основе количества двоичных файлов использующих эти языки в системе iOS 17

Язык

Процент использования %

C++

12%

С

5%

Swift

17%

Objective-C

61%

Из нее мы можем выделить

  1. Objective-C по-прежнему лежит в основе iOS и используется прямо или косвенно большинством приложений

  2. Внедрение Swift продолжает стремительно расти

  3. Доля Objective-C, C и C++ продолжает снижаться по сравнению с другими iOS

Вывод по разделу

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

2 - Историческая справка

Представьте себе 1970-е годы, время, когда компьютеры только начинали проникать в повседневную жизнь. Именно в это время группа исследователей из Xerox PARC создала Smalltalk - один из первых объектно-ориентированных языков программирования. Это было революционное время, когда программирование стало напоминать диалог между объектами.

Smalltalk: Рождение объектно-ориентированного программирования

Smalltalk, созданный Аланом Кеем и его командой, изменил представление о том, как программы могут быть структурированы. В Smalltalk всё — от чисел до текстов — было объектами, которые взаимодействовали друг с другом с помощью сообщений. Эта концепция легла в основу многих современных языков программирования, включая Objective-C.

Objective-C: Мост между C и объектами

Перенесемся в начало 1980-х годов, когда Брэд Кокс и Том Лав создали Objective-C. Они взяли мощь языка C и объединили её с элегантностью Smalltalk, чтобы предоставить разработчикам возможность работать с объектами, не отказываясь от низкоуровневого контроля. Objective-C позволял разработчикам использовать знакомый синтаксис C, обогащённый объектно-ориентированными возможностями Smalltalk. Эта комбинация сделала язык чрезвычайно гибким и мощным.

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

Swift: Современное развитие

Спустя десятилетия, в 2014 году, Apple представила Swift — язык, который объединил лучшие идеи прошлого и предложил новый взгляд на программирование. Swift, разработанный под руководством Криса Латтнера, упростил синтаксис, повысил безопасность и сделал программирование более доступным для новичков, сохраняя при этом высокую производительность.

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

3 - Сильные и слабые стороны

Исходя из моего опыта, разработчики без фундаментальных знаний об iOS разработке, всё чаще предпочитают работать только со Swift и избегают Objective-C, считая его устаревшим, сложным и не соответствующим современным стандартам разработки. Однако знание обоих языков может дать значительное преимущество, так как Objective-C остается актуальным и востребованным в определенных ситуациях, подобно другим языкам программирования, основанным на C. 

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

Преимущества Objective-C

1 - Зрелость и стабильность

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

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

Несмотря на старый синтаксис, который может казаться сложным по сравнению с современными языками, Objective-C остаётся мощным и надёжным языком, поддерживающим множество существующих приложений. Зрелость и стабильность делают его идеальным выбором для проектов, требующих надежности и длительной поддержки.

2 - Динамическая природа

Objective-C — это язык программирования с мощной и гибкой runtime-системой, что делает его уникальным среди других языков. В отличие от языков, где многие решения принимаются на этапе компиляции, Objective-C позволяет откладывать эти решения до выполнения программы. Это означает, что программа может изменять свою структуру и поведение динамически, во время работы, что открывает широкие возможности для гибкого и адаптивного программирования.

Почему это важно?

Runtime система Objective-C предоставляет разработчикам инструменты для изменения классов и объектов прямо во время выполнения программы. Это позволяет выполнять такие задачи, как добавление новых методов, изменение существующих, а также манипуляции с классами и их экземплярами. Благодаря этому Objective-C становится чрезвычайно гибким инструментом для разработки сложных и динамических приложений.

Method Swizzling

Одним из ярких примеров возможностей runtime-системы Objective-C является техника Method Swizzling. Эта техника позволяет изменять реализацию существующих методов в классе на этапе выполнения программы. Это означает, что можно заменить одну реализацию метода другой, не изменяя исходный код класса.

Как это работает?

Objective-C предоставляет API для работы с классами и методами на уровне runtime, что позволяет динамически изменять их. Это делается путем замены указателя на метод в таблице диспетчеризации методов класса. Таким образом, каждый раз, когда вызывается изменённый метод, будет выполняться его новая версия.

Преимущества свизлинга:

- Изменение поведения методов: Позволяет изменять существующие методы без изменения их исходного кода

- Гибкость: Позволяет добавлять дополнительную функциональность к существующим классам

Недостатки свизлинга:

- Риск ошибок: Неправильное использование свизлинга может привести к трудно отслеживаемым ошибкам и нестабильности программы

- Совместимость: Может вызвать проблемы с совместимостью в будущем, если API классов изменятся

Метод свизлинга делает Objective-C чрезвычайно гибким и мощным, но требует осторожности в использовании из-за потенциальных проблем с надёжностью и поддерживаемостью кода.

Недостатки Objective-C

1 - Сложный синтаксис

Objective-C имеет синтаксис, который может казаться запутанным и трудным для освоения, особенно для новых разработчиков. Да, он стабильный и точно лучше остальных Си подобных языков, но читать его бывает тяжело. Вот пример, который иллюстрируют сложность синтаксиса Objective-C.

Синтаксис Objective-C может показаться сложным, особенно для разработчиков, привыкших к более современным языкам программирования, таким как Swift. Однако понимание его основных принципов работы может помочь в работе.

2 - Менее безопасный

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

В Objective-C вызов методов у nil объектов безопасен, но может привести к неожиданным результатам. Этот код корректно обрабатывает nil объект, но важно знать, что это поведение может привести к непредсказуемым последствиям в приложении.

3 - Ограниченные современные функции

Objective-C, в отличие от современных языков программирования, таких как Swift, не поддерживает дженерики, которые позволяют явно указывать тип данных, используемый в коллекциях и других структурах. Вместо этого Objective-C использует универсальный тип id, который позволяет работать с объектами любого типа. Это придает коду большую гибкость, но также вводит некоторые риски, связанные типобезопасностью.

Класс Stack использует тип id для хранения элементов в стеке и работы с ними. Вы можете добавлять объекты любых типов в стек и извлекать их в том же виде. Такой подход делает код гибким, но требует осторожности, поскольку ошибки типа будут обнаружены только во время выполнения программы, а не на этапе компиляции, как раз из-за особенностей Objective-C. Это может привести к неожиданным сбоям, если вы попытаетесь использовать объект неподходящего типа.

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

Промежуточный вывод по Objective-C

Знание сильных и слабых сторон Objective-C помогает принимать обоснованные решения при выборе технологий для проектов. С одной стороны, зрелость, стабильность и совместимость с C/C++ делают Objective-C надежным выбором для многих крупных проектов. С другой стороны, сложный синтаксис, менее строгая безопасность и ограниченные современные функции могут осложнить разработку и сопровождение кода.

При принятии решения о выборе Objective-C для проекта важно учитывать несколько ключевых факторов, связанных с его сильными и слабыми сторонами.

Выбор Objective-C целесообразен, если выполнены условия:

  1. Вы работаете над проектом, который требует интеграции с кодовой базой, написанной на Objective-C

  2. Ваши требования к гибкости и динамическому поведению программы высоки, и вы готовы справляться с потенциальными трудностями, связанными с менее строгой типизацией и сложным синтаксисом

  3. Проект будет использовать существующие библиотеки и фреймворки, которые уже написаны на Objective-C

Рассмотрите другие технологии, если:

  1. Вы планируете новый проект и ищете язык с современными функциями и лучшей поддержкой типобезопасности, таким как Swift

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

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

Преимущества Swift

1 - Простой и понятный синтаксис

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

Swift предлагает чистый и лаконичный синтаксис для объявления классов, методов и создания объектов, что делает код легко читаемым и понятным. Интерполяция строк, явное объявление параметров и отсутствие сложного синтаксиса делают его более доступным для новичков за счёт низкого порога входа и удобным для опытных разработчиков

2 - Безопасность типов

Swift строго типизирован, что помогает предотвратить ошибки, связанные с некорректным использованием данных.

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

3 - Современные возможности

Swift демонстрирует использование множества современных возможностей, таких как:

  1. Опционалы - В Objective-C нет встроенного типа опционалов, как в Swift, но можно использовать nil для проверки, инициализирован ли объект

  2. Кортежи - Objective-C не поддерживает кортежи в традиционном смысле. Для аналогичных целейобычно используют словари

  3. Замыкания - Objective-C поддерживает блоки(blocks), которые предоставляют похожий функционал и предоставляют возможность использовать функциональное программирование, но синтаксис может быть менее удобным по сравнению с замыканиями в Swift. Замыкания в Swift предлагают более лаконичный и читаемый способ работы с функциями и коллекциями

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

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

4 - Modern Concurrency

Swift включает в себя встроенные возможности для конкурентного программирования, обеспечивая простоту и безопасность при работе с потоками:

  1. Async/Await: Swift предоставляет простые конструкции для написания асинхронного кода с помощью ключевых слов async и await, упрощая обработку асинхронных операций

  2. Actors: Swift предлагает концепцию акторов для безопасного управления состоянием в многопоточных средах,  снижает вероятность race condition

Swift делает конкурентное программирование более доступным, интегрируя современные подходы прямо в язык, что позволяет разработчикам писать более эффективный и безопасный код с минимальными усилиями. В Objective-C для работы с конкурентностью в основном используются такие библиотеки, как Grand Central Dispatch (GCD) или операции NSOperation, которые, хотя и мощные, требуют более низкоуровневого управления и могут быть более сложными в использовании.

Недостатки Swift

1 - Неоптимизированная производительность

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

Swift может сталкиваться с проблемами производительности при работе с большими объемами данных или сложными алгоритмами.

Для критических областей кода, требующих высокой производительности, такие как библиотеки для обработки данных, C++ может быть предпочтительным выбором из-за своей эффективности.

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

Telegram активно использует высокопроизводительные библиотеки, написанные на C/C++, особенно для обработки мультимедиа (видео, изображения), криптографии и сетевых операций. Это позволяет ускорить критичные для производительности задачи. Например, такие задачи, как сжатие данных, кодирование и декодирование мультимедийных форматов или шифрование данных, часто реализуются на этих языках, поскольку они предлагают более низкий уровень контроля и лучшую производительность, чем Swift.

Кроме того, Telegram может интегрировать нативные библиотеки C/C++ через механизмы вроде Swift/Objective-C++ interoperability, что позволяет объединять эти языки для решения специфичных задач в iOS-приложении.

Хотя основная часть интерфейса и логики приложения реализована на Swift и Objective-C, использование C или C++ для оптимизации тяжелых операций вполне возможно и даже типично для таких масштабных приложений, как Telegram.

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

2 - Скорость изменения

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

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

Какие задачи можно решить тем или иным языком

Objective-C:

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

  2. Интеграция со старыми API - Некоторые старые API и фреймворки изначально разработаны для Objective-C, что делает его использование более удобным

Swift:

  1. Читаемости и безопасности - Swift предлагает простой и выразительный синтаксис, а также строгую типизацию, что снижает вероятность ошибок и упрощает поддержку кода

  2. Современные фреймворки - Новые API от Apple, такие как SwiftUI и Combine, изначально разработаны для Swift, предоставляя более удобные инструменты для создания современных приложений

  3. Прямая работа с C и C++ - Swift теперь поддерживает взаимодействие с C и C++ кодом, что упрощает использование низкоуровневых библиотек в проектах

Уникальные особенности каждого языка

Метапрограммирование с помощью селекторов на Objective-C

Objective-C поддерживает метапрограммирование через селекторы, что позволяет динамически выбирать и вызывать методы во время выполнения программы. Это предоставляет разработчикам возможность писать более гибкий и расширяемый код.

Селекторы: Это тип SEL(сокращение от "selector"), который указывает на метод, который будет вызван. Они позволяют динамически выбирать, какой метод вызвать, что делает код более гибким и адаптируемым к изменениям в логике выполнения.

Метод respondsToSelector: Проверяет, поддерживает ли объект указанный метод, что предотвращает попытки вызвать несуществующий метод и защищает от ошибок выполнения.

Метод performSelector: Используется для динамического вызова метода по селектору, передавая аргументы. Это позволяет выполнять методы, выбранные на этапе выполнения программы.

В Swift также можно использовать метапрограммирование с помощью селекторов, но это делается в контексте взаимодействия с Objective-C кодом.

Структуры с Copy-On-Write в Swift

Swift предоставляет мощные структуры, которые имеют поведение Copy-On-Write, что позволяет эффективно работать с данными, минимизируя ненужные копии и сохраняя производительность.

Структуры в Swift: Swift предоставляет мощные возможности для использования структур, которые являются типами значений(value type) и обеспечивают семантику копирования. Это означает, что структуры копируются при присваивании или передаче функции.

Copy-On-Write (COW): Это оптимизация, которая позволяет избежать ненужного копирования данных до тех пор, пока они не изменятся. При изменении копии структуры создается новая версия, минимизируя затраты памяти.

Мутирующие методы: Используются для изменения свойств структуры. Если структура меняется, она создает копию данных, что позволяет безопасно работать с неизменяемыми данными, увеличивая производительность и обеспечивая безопасное управление памятью.

В Objective-C нет встроенной поддержки механизма Copy-On-Write для типов значений(value type), как это реализовано в Swift. Однако, мы можем вручную реализовать подобное поведение с помощью классов и других паттернов программирования.

Вывод по разделу

Уникальные возможности каждого языка могут существенно облегчить решение специфических задач, а понимание этого, даёт возможность реализовать хорошую систему:

  1. Objective-C с метапрограммированием и с селекторами позволяет создавать динамические и адаптируемые системы, где поведение может изменяться в зависимости от условий выполнения

  2. Swift с его оптимизациями структур с Copy-On-Write помогает управлять памятью эффективно и производительно

Эти особенности расширяют возможности разработки и позволяют создавать более эффективные и оптимизированные приложения, используя преимущества каждого языка.

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

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

4 - Совместимость

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

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

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

Вызов Swift кода из Objective-C

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

Вызов Objective-C кода из Swift

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

Совместимость между Swift и Objective-C позволяет разработчикам интегрировать современные возможности Swift в существующие проекты на Objective-C и использовать проверенные временем решения из Objective-C в новых проектах на Swift. Это также упрощает переход между языками и помогает использовать лучшие инструменты для решения конкретных задач.

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

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

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

Вызов C функции из Objective-C

Objective-C и C имеют отличное взаимодействие, благодаря совместимости, предоставляемой стандартом C. Это позволяет легко интегрировать функции, написанные на C, в Objective-C код. Использование #import для включения C заголовочных файлов в Objective-C код позволяет разработчикам использовать низкоуровневые функции и библиотеки, написанные на C, без необходимости переписывать их на Objective-C. Это упрощает интеграцию существующих C библиотек и оптимизирует использование кода, уже проверенного временем.

Вызов C++ функции из Swift

Взаимодействие между Swift и C++ требует использования промежуточного слоя, так как Swift не поддерживает прямую работу с C++ из-за его сложного синтаксиса и особенностей. Однако, можно обойти это ограничение с помощью extern "C", который позволяет C++ функции быть вызванными из Swift. Для этого используется Bridging Header файл, который объявляет C++ функции, чтобы они могли быть вызваны из Swift-кода. Это позволяет интегрировать высокопроизводительные модули и библиотеки на C++ в Swift-проекты, сохраняя производительность и функциональность.

Вывод по разделу

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

Мы стали лучше понимать возможности обоих языков, их совместимости с более продвинутыми языками и приблизились еще на шаг к тому, чтобы избавиться от страха перед Objective-C и за счёт насмотренности и понимания разных механизмов языков стать более компетентными специалистами.

5 - Миграция

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

Переход от старого к новому

  1. Постепенное внедрение - Не стоит сразу переписывать весь проект на новом языке или фреймворке. Начните с новых модулей или компонентов, которые можно изолировать от остальной части приложения. Это позволит постепенно освоить новые инструменты и минимизировать риски. Скорее всего вашей команде понадобиться время на смену мышления, для адаптации к новым подходам и наработки определенного опыта для работы с новым инструментом

  2. Использование интеропа - Как мы уже видели в предыдущих разделах, Swift и Objective-C могут легко взаимодействовать друг с другом. Это позволяет интегрировать новый код на Swift в существующие проекты на Objective-C и наоборот

  3. Рефакторинг - Используйте возможности рефакторинга для постепенного улучшения и модернизации кода. Это может включать в себя замену устаревших API на новые, улучшение архитектуры приложения и оптимизацию производительности

Маневрирование в обратную сторону

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

  2. Интеграция современных паттернов - Даже в старых проектах можно интегрировать современные паттерны программирования, такие как реактивное или декларативное программирование с помощью SwiftUI или Combine. Это поможет улучшить качество кода и упростить его поддержку

  3. Использование существующих инструментов - Не стоит сразу отказываться от использования проверенных временем библиотек и фреймворков, таких как Objective-C, если они соответствуют требованиям проекта и обеспечивают необходимую функциональность. Дайте команде время для адаптации и возможности поработать с новыми инструментами в контексте привычного проекта

  4. Обратная совместимость - При разработке новых фичей и модулей важно учитывать обратную совместимость с существующим кодом. Это позволит избежать проблем при интеграции и обеспечит стабильность приложения

Ключевые стратегии перехода

  1. Анализ требований - Прежде чем начинать переход, важно тщательно проанализировать требования проекта и понять, какие инструменты и технологии лучше всего подходят для конкретных задач

  2. Планирование и поэтапное внедрение - Создайте план поэтапного внедрения новых технологий, включая конкретные цели и временные рамки. Это поможет организовать процесс и избежать потенциальных проблем

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

Вывод по разделу

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

6 - Заключение

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

Краткий обзор основных моментов

  1. Статистика использования языков - Приведенная статистика показала, что Objective-C остается важным и востребованными инструментом, подтверждая свою актуальность и необходимость его освоения для успешной разработки

  2. Сильные и слабые стороны языков - Объяснение преимуществ и недостатков каждого языка, таких как метапрограммирование в Objective-C и Copy-On-Write в Swift, помогает разработчикам делать осознанный выбор и использовать правильные инструменты для конкретных задач

  3. Совместимость - Знание общих механизмов, таких как возможность интеграции кода между Objective-C и Swift, улучшает гибкость и эффективность разработчиков, позволяя им использовать преимущества всех доступных инструментов

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

Вывод

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

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

Таким образом, освоение полного арсенала инструментов iOS разработки не только повышает вашу ценность как специалиста, но и помогает быть более востребованным на рынке и способным решить проблемы любого приложения. これであなたも本物の忍者だ。

Рекомендуемые материалы для расширения кругозора

  1.  Подробнее о различиях между UIKit и SwiftUI и их применении вы можете прочитать в моей статье на Хабре

  2. Запись стрима на канале Cofee&Code, в котором разбирают код стартапа c AI на борту, в котором используется method swizzling

  3. Выпуск подкаста Mobile People Talks о legacy

  4. Интервью с Дмитрием Кузнецовым о том, как нужно бороться с legacy

  5. Небольшая статья о том, как с небольшими усилиями и щепоткой Objective-C использовать Method Swizzling в Swift

  6. Доклад Андрея Филипенко о прямом интеропе Swift с С++

  7. Доклад моего коллеги Кирилла Шумакова о сборке Objective-C и Swift модулей

Комментарии (12)


  1. Alexufo
    23.10.2024 08:05

    c++ в swift c какой версии доступен? Он очень свеж. Да даже async await свифтовые капец какие свежие (я думал они будут по умолчанию в языке как только он появился... уж сильно устоявшийся паттерн). Пока без Objective-C, который работает вообще везде обойтись трудно, если нужны с++. Думаю лет 5 еще такое заявление будет работать.


    1. gnatyuk_sergey Автор
      23.10.2024 08:05

      Интероп в Swift 5.9 появился, в рекомендашках как раз закинул докладик с Мобиуса, в котором Андрей Филипенко поковырял фичу

      Асинк авейт вообще интересным был, его когда Apple выкатила, пришлось смотреть, как работает в других языках, типа котлина или C#, а то была проблема с тестированием некоторых историй


      1. aamonster
        23.10.2024 08:05

        Вроде интероп с крестиками всё ещё проблемный. На работе время от времени на него смотрим (есть желание заменять ObjC на Swift, где получается без большой боли: код на Swift получается прозрачнее, так что это хороший задел на будущее), нам актуально.


      1. Alexufo
        23.10.2024 08:05

        Swift 5.9 всего год назад вышел... IOS17, 16? если требование с 13 то... пока никак)


  1. varton86
    23.10.2024 08:05

    Сейчас по работе каждый день пишу на obj-c, хотя до этого несколько лет писал на swift. Гибкий и быстрый язык, а к синтаксису быстро привыкаешь.


    1. Alexufo
      23.10.2024 08:05

      Очень не удобно когда не знаешь класс объекта, которые возвращают методы. Xcode мог бы быть и поумнее в подсказках... приходится лазить копировать..


  1. nagayev
    23.10.2024 08:05

    Вода водой


  1. Bardakan
    23.10.2024 08:05

    Почему вы видите только положительные стороны строгой типизации? Для начала такой строгой типизации нет наверное ни в одном языке - вы даже 2 и 2.5 не сможете сложить из-за того, что они разных типов.

    Со строками там вообще лютая дичь - результат поиска подстроки в строке - это не строка, а произвольный несовместимый тип. Поиск позиции подстроки тоже завязан не на int, а на некий произвольный тип


    1. gnatyuk_sergey Автор
      23.10.2024 08:05

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


  1. kotovsky_art
    23.10.2024 08:05

    С каких пор Легаси это какой-то плохо структурированный или недокументированный код, полный техдолга?

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

    Никакой связи у понятия «Легаси» с качественными характеристиками кода нет.


    1. Alexufo
      23.10.2024 08:05

      Потому что либо приходит зеленый на твой код, либо ты его писал зеленым)) и так и так получишь)) Нейропластичность, думаю, это больше речь про вникание в новую архитектуру


      На счет легаси и качеством не соглашусь. Качество зачастую обеспечивает новый опыт, это или мозги IDE или новые языковые конструкции, с которыми удобнее не стрелять в ногу или же они дают меньше когнитивной нагрузки.


    1. gnatyuk_sergey Автор
      23.10.2024 08:05

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