Рубріки: Теория

Objective-C: история создания, возможности и особенности

Сергій Бондаренко

Что такое Objective-C

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

iPhone тоже работает на Objective-C

Отличительная особенность этого языка состоит в том, что оно является расширением для другого языка программирования – С. Несмотря на то, что в последнее время Objective-C существенно уступает более прогрессивному, простому и удобному SWIFT, разработка Apple все еще остается актуальной и вызывает интерес.

 

История появления Objective-C

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

Книга о Smalltalk-80

Таким решением стал один из первых объектно-ориентированных языков с динамической типизацией – Smalltalk. Забавно, что, хотя он разрабатывался в семидесятых, его более или менее сформировавшаяся версия называлась Smalltalk-80 (наверное, его разработчики из научно-исследовательского центра Xerox PARC давали имя с прицелом на будущее). Уже в то время Smalltalk мог похвастаться возможностями, которые остаются актуальными и по сей день – у него был сборщик мусора, динамическая типизация. Программы, написанные на Smalltalk компилировались в байткод и выполнялись виртуальной машиной, что позволяло запускать код на любом оборудовании.

Взяв за основу главные принципы языка Smalltalk, был создан Objective-C. Создателем Objective-C считается Брэд Кокс, который старался в начале восьмидесятых сделать такой язык программирования, в котором была бы решена проблема повторяемости кода. Objective-C строился на базовых допущениях: класс – самостоятельный полноценный объект, передача сообщений между классами, динамическое типизирование. Самое главное, что отличало этот язык — гибкость. Программист мог писать код на С, а затем просто вставлять его в Objective-C и программа работала.

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

Интерфейс NeXTEP OS

В 1988 программисты NeXT разработали для Objective-C компилятор и SDK. А в 1992 году доработкой Objective-C и компилятора занялись также и участники проекта GNU, так GCC получил совместимость с Objective-C. С покупкой NeXT, Apple приобрела и этот SDK (включая компилятор, библиотеки и среду разработки). IDE получило название Xcode, а GUI – Interface Builder. Фреймворк Cocoa (API для macOS) сейчас является наиболее популярной средой разработки программ на Objective-C.

Современная ОС от Apple

В феврале 2008 Apple представил iPhone SDK 2.0, который позволял разрабатывать программы под платформу iOS. Это поспособствовало популяризации языка программирования Objective-C и дало возможность компании Стива Джобса быстро заполнить AppStore огромным числом приложений.

Синтаксис

С Objective-C можно работать практически на любом дистрибутиве GNU/Linux через компилятор gobjc, включенный в набор компиляторов GNU Compiler Collection.

 Разработка в Objective-C под ОС Windows возможна через бесплатные эмуляторы среды POSIX:

  • mingw;
  • cygwin;
  • сервисы Microsoft Windows для UNIX.

Когда программист С смотрит на код Objective-C он видит знакомый синтаксис с некоторыми дополнениями — квадратными скобками, значком “@“, код, начинающийся с NS (наследие NeXTSTEP) и др

Самое простое приложение, которое выводит на экран текстовое сообщение, выглядит в Objective-C так:

int main(int argc, const char * argv[]) {

    @autoreleasepool {

           NSLog(@""Highload.today"");

    }

    return 0;

}

 

Когда нужно упаковать в объекте Objective-C целое, вещественное или логическое значение, используется класс NSNumber.

NSNumber *someNumber = [NSNumber numberWithInt:1];

с литеральным синтаксисом:

NSNumber *someNumber = @1;

Литеральный синтаксис распространяется на все типы данных:

NSNumber *intNumber = @1;

NSNumber *floatNumber = @2.5f;

NSNumber *doubleNumber = @3.14159;

NSNumber *boolNumber = @YES;

NSNumber *charNumber = @'a';

Переменные в Objective-C задаются следующим образом:

int hours = 24;

/* где int – это тип переменной, hours – имя, 24 – значение */

Если переменные состоят из двух слов, то второе слово пишется с большой буквы.

Обращение к методу

Когда в Objective-C идет обращение к какому-нибудь методу, это трактуется не как обращение к функции, а как отправка сообщения (с указанием аргументов и имени), аналогично тому, как это реализовано в Smalltalk.  В этом заключается принципиальное отличие Objective-C от С++, который является функция-ориентированным языком. Поскольку Objective-C это объектно-ориентированный язык, вполне ожидаемо, что он соответствует основным принципам ООП:

  • инкапсуляция
  • сокрытие данных
  • наследование
  • полиморфизм

Любому объекту, используемому в коде, можно отправить сообщение с любым содержанием. Объект сам может не обрабатывать сообщение. Вместо этого он может делегировать (переотправить) сообщение другому объекту, который уже его обработает. Объекты могут находиться в разных адресных пространствах и на разных ПК. 

Все объекты классов Objective-C размещаются в динамической памяти. Каждый объект в Objective-C имеет собственный идентификатор id. Вместо id можно использовать и более привычное обозначение с явным указанием класса. В идентификаторах Objective-C нельзя использовать знаки препинания (символы @, $ и %). Кроме того, следует помнить, что Objective-C это регистрозависимый язык программирования. 

Конструкция для отправки сообщений выглядит так:

[receiver method];

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

[receiver methodAndFirstArgument: 20 andLastArgument: 30];

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

[receiver undefinedNumberParameters: oneParam, twoParam, threeParam, fourParam, fiveParam, sixParam, sevenParam];

Копирование объектов

Данный язык программирования допускает копирование любых объектов. Для этого, следует обратиться к методу copy, определённому в классе NSObject. При создании копии вызывается метод copyWithZone протокола NSCopying. NSObject не поддерживает данный протокол, поэтому протокол NSCopying должен реализовываться в классах-наследниках. Различают два вида данной операции – поверхностная копия (shallow copy) и глубокая копия (deep copy). Отличие одного типа копирования от другого состоит в том, что при выполнении поверхностного копирования копируются не данные, а лишь указатель на объект с данными. При глубоком копировании копируется объект с данными.

Поскольку Objective-C представляет собой «обертку» для языка С или С++, в нем используются два типа файлов – заголовочные файлы (.h) и файлы реализации(.m).

Файлы, созданные при создании класса, могут выглядеть так:

//EOCPerson.h

#import

@interface EOCPerson:NSObject

@property (nonatomic, copy) NSString *firstName

@property (nonatomic, copy) NSString *lastName

@end

//EOCPerson.m

#import "EOCPerson.h"

@implementation EOCPerson

//Реализация методов

@end

 

Допустим, в классе Mycompany существует instance-переменная nameofcompany.

@interface Mycompany : NSObject

{

     NSString *nameofcompany;

}

 

Для доступа к ней оптимальнее всего обратиться к свойствам, которые появились в Objective-C 2.0. Чтобы объявить свойства используется ключевое слово @property.

@property (retain) NSString *nameofcompany;

В скобках перечисляются атрибуты доступа к instance-переменной. 

Булевый тип

К сожалению булевые данные в данном языке отсутствуют как тип. Поскольку для программирования это имеет критическое значение, его добавляют искусственно,  как BOOL ( по факту это unsigned char). Он может принимать значения либо YES, либо NO (так реализовано в операционных системах NextStep, Mac OS X).

Протоколы

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

Пример описания протокола

@protocol TestProtocol 

-(void) test;

-(void) testWithName: (NSString *) name;

@end

Циклы

В Objective-C используются циклы следующих типов:

  • while loop – Повторяет оператор или группу операторов, пока заданное условие истинно. Он проверяет условие до выполнения тела цикла.
  • for loop – Выполняет последовательность операторов несколько раз, сокращая счетчик кода, управляющего переменной цикла.
  • do…while loop — Аналог оператора while, за исключением того, что он проверяет условие в конце тела цикла.
  • nested loops  – Позволяет применять один или набор циклов внутри любого другого цикла, например, while, for или do..while.

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

#include <stdio.h>

int main (int argc, const char *argv[]) {

    for (int i = 0; i < argc; i++) {

        printf("arg %d : %s\n", i, argv[i]);

    }

    return 0;

}

 

Пример цикла

Цикл обрабатывает текст, в результате чего программа выводит на печать новое слово, изменяя счетчик на единицу. Теперь скомпилируем программу и выполним в командной строке.

В Objective-C доступен контроль многопоточных вычислений. Используя директиву @synchronized ()  какую-то часть кода можно закрыть от одновременного исполнения паралельными потоками.

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

  • Objective-C работает медленнее SWIFT
  • Код, написанный на Objective-C, работает в Swift. А, вот, наоборот — нет
  • Отсутствует возможность работы с декларативной областью «пространство имен»
  • В Objective-C нет множественного наследования
  • Механизм динамического запуска делает методы оптимизации непригодными для использования и снижает производительность.

Примеры кода на Objective-C

И, напоследок, рассмотрим несколько примеров приложений на Objective-C. 

Код приложения, которое вычисляет корни квадратного уравнения:

#include

#include

int main()

{

int F, G, H, J;

printf("F = ");

scanf("%d", &F);

if (F == 0) {

printf("Ошибка с аргументами квадратного уравнения.");

return 0;

}

printf("G = ");

scanf("%d", &G);

printf("H = ");

scanf("%d", &H);




J = G * G - 4 * F * H;

if (J == 0) {

printf("x = %f\n", -G / 2.0 / F);

return 0;

}




if (J > 0) {

printf("x1 = %f\nx2 = %f\n",

(-G + sqrt(J)) / 2.0 / F, (-G - sqrt(J))/ 2.0 / F);

} else {

printf("x1 = (%f, %f)\nx2 = (%f, %f)\n",

-G / 2.0 / F, sqrt(-J) / 2.0 / F, -G / 2.0 / F, -sqrt(-J) / 2.0 /F);

}

return 0;

} 

Пример кода программы для перевода текста в регистр Camel Case 

#import <Foundation/Foundation.h>




#define LETTERS @"ABCDFEGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"




NSString *camelCase(NSString *s) {

  return [[[s capitalizedString] componentsSeparatedByCharactersInSet:[[NSCharacterSet characterSetWithCharactersInString:LETTERS] invertedSet]] componentsJoinedByString:@""];

}

int main (int argc, const char * argv[]) {

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    NSLog(@"%@", camelCase(@"beliberda"));

    NSLog(@"%@", camelCase(@"primer-Dva "));

    NSLog(@"%@", camelCase(@"!!! eto_cHto_esche_PRIMER?.."));

    [pool drain];

    return 0;

}

 

Заключение.

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

Останні статті

Обучение Power BI – какие онлайн курсы аналитики выбрать

Сегодня мы поговорим о том, как выбрать лучшие курсы Power BI в Украине, особенно для…

13.01.2024

Work.ua назвал самые конкурентные вакансии в IТ за 2023 год

В 2023 году во всех крупнейших регионах конкуренция за вакансию выросла на 5–12%. Не исключением…

08.12.2023

Украинская IT-рекрутерка создала бесплатный трекер поиска работы

Unicorn Hunter/Talent Manager Лина Калиш создала бесплатный трекер поиска работы в Notion, систематизирующий все этапы…

07.12.2023

Mate academy отправит работников в 10-дневный оплачиваемый отпуск

Edtech-стартап Mate academy принял решение отправить своих работников в десятидневный отпуск – с 25 декабря…

07.12.2023

Переписки, фото, история браузера: киевский программист зарабатывал на шпионаже

Служба безопасности Украины задержала в Киеве 46-летнего программиста, который за деньги устанавливал шпионские программы и…

07.12.2023

Как вырасти до сеньйора? Девелопер создал популярную подборку на Github

IT-специалист Джордан Катлер создал и выложил на Github подборку разнообразных ресурсов, которые помогут достичь уровня…

07.12.2023