Из Википедии, бесплатной энциклопедии
Перейти к навигации Перейти к поиску

Objective-C - это объектно-ориентированный язык программирования общего назначения , который добавляет к языку программирования C обмен сообщениями в стиле Smalltalk . Это был основной язык программирования, поддерживаемый Apple для macOS , iOS и соответствующих интерфейсов программирования приложений (API), Cocoa и Cocoa Touch , до появления Swift в 2014 году [3].

Первоначально язык был разработан в начале 1980-х годов. Позже он был выбран в качестве основного языка, используемого NeXT для своей операционной системы NeXTSTEP , от которой произошли macOS и iOS. [4] Переносимые программы Objective-C, которые не используют библиотеки Apple или те, которые используют части, которые могут быть перенесены или переопределены для других систем, также могут быть скомпилированы для любой системы, поддерживаемой GNU Compiler Collection (GCC) или Clang .

Программные файлы «реализации» исходного кода Objective-C обычно имеют расширение .m , в то время как файлы заголовка / интерфейса Objective-C имеют расширения .h , такие же, как файлы заголовков C. Файлы Objective-C ++ обозначаются расширением файла .mm .

История [ править ]

Objective-C был создан в первую очередь Брэдом Коксом и Томом Лавом в начале 1980-х годов в их компании Productivity Products International (PPI) . [5]

Приводя к созданию своей компании, как были введены в Smalltalk в то время как в ITT Corporation Программирование Technology Center «s в 1981. Самые ранние работы на Objective-C прослеживает около того времени. [6] Кокса заинтриговали проблемы истинного повторного использования в разработке и программировании программного обеспечения. Он понял, что такой язык, как Smalltalk, будет неоценимым средством создания сред разработки для системных разработчиков в ITT. Однако он и Том Лав также признали, что обратная совместимость с C была критически важна в среде инженеров ITT в области телекоммуникаций. [7]

Кокс начал писать препроцессор для C, чтобы добавить некоторые возможности Smalltalk. Вскоре у него была рабочая реализация объектно-ориентированного расширения языка C , которую он назвал «OOPC» для объектно-ориентированного предварительного компилятора. [8] Лав был нанят компанией Schlumberger Research в 1982 году и имел возможность приобрести первую коммерческую копию Smalltalk-80, которая в дальнейшем повлияла на развитие их детища. Чтобы продемонстрировать реальный прогресс, Кокс показал, что создание взаимозаменяемых программных компонентовдействительно требовалось лишь несколько практических изменений существующих инструментов. В частности, они должны были обеспечивать гибкую поддержку объектов, поставляться с полезным набором библиотек и позволять объединять код (и любые ресурсы, необходимые для кода) в один кроссплатформенный формат.

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

Популяризация через NeXT [ править ]

В 1988 году NeXT лицензировал Objective-C у StepStone (новое название PPI, владельца торговой марки Objective-C) и расширил компилятор GCC для поддержки Objective-C. NeXT разработала библиотеки AppKit и Foundation Kit, на которых были основаны пользовательский интерфейс NeXTSTEP и Interface Builder. Хотя рабочие станции NeXT не смогли оказать большого влияния на рынок, инструменты получили широкое признание в отрасли. Это привело к тому, что NeXT отказалась от производства оборудования и сосредоточилась на программных инструментах, продав NeXTSTEP (и OpenStep) в качестве платформы для индивидуального программирования.

Чтобы обойти условия GPL , NeXT изначально намеревался поставлять интерфейс Objective-C отдельно, позволяя пользователю связать его с GCC для создания исполняемого файла компилятора. Хотя первоначально этот план был принят Ричардом М. Столлманом , этот план был отклонен после того, как Столмен проконсультировался с юристами GNU, и NeXT согласился сделать Objective-C частью GCC. [9]

Работой по расширению GCC руководил Стив Нарофф, который присоединился к NeXT из StepStone. Изменения компилятора были сделаны доступными в соответствии с условиями лицензии GPL , но библиотеки времени выполнения - нет, что сделало вклад с открытым исходным кодом непригодным для широкой публики. Это привело к тому, что другие стороны разработали такие библиотеки времени выполнения под лицензией с открытым исходным кодом. Позже Стив Нарофф также был основным сотрудником Apple по созданию интерфейса Objective-C для Clang .

Проект GNU начал работу над своей свободной программной реализацией Cocoa под названием GNUstep , основанной на стандарте OpenStep . [10] Деннис Глаттинг написал первую среду выполнения GNU Objective-C в 1992 году. Среда выполнения GNU Objective-C, которая используется с 1993 года, была разработана Крестеном Крабом Торупом, когда он был студентом университета в Дании . [ необходима цитата ] Торуп также работал в NeXT с 1993 по 1996 год. [11]

Разработка Apple и Swift [ править ]

После приобретения NeXT в 1996 году, Apple Computer используется OpenStep в тогдашнем новой операционной системе Mac OS X . Это включало Objective-C, инструмент разработчика NeXT на основе Objective-C, Project Builder и его инструмент дизайна интерфейса Interface Builder , которые теперь объединены в одно приложение Xcode . Большая часть текущего API Cocoa от Apple основана на интерфейсных объектах OpenStep и является наиболее важной средой Objective-C, используемой для активной разработки.

На WWDC 2014 Apple представила новый язык Swift , который был охарактеризован как «Objective-C без C».

Синтаксис [ править ]

Objective-C представляет собой тонкий слой поверх C и является «строгим надмножеством » C, что означает, что можно скомпилировать любую программу C с помощью компилятора Objective-C и свободно включать код языка C в класс Objective-C. [12] [13] [14] [15] [16] [17]

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

Сообщения [ править ]

Модель объектно-ориентированного программирования Objective-C основана на передаче сообщений экземплярам объектов. В Objective-C метод не вызывается ; один отправляет сообщение . Это не похоже на модель программирования в стиле Simula, используемую в C ++ . Разница между этими двумя концепциями заключается в том, как выполняется код, на который ссылается имя метода или сообщения. В языке в стиле Simula имя метода в большинстве случаев привязано компилятором к части кода в целевом классе. В Smalltalk и Objective-C цель сообщения решается во время выполнения, при этом принимающий объект сам интерпретирует сообщение. Метод идентифицируется селекторомили SEL - уникальный идентификатор для каждого имени сообщения, часто просто заканчивающаяся NUL строка, представляющая его имя - и преобразованный в указатель метода C, реализующий его: IMP . [18] Следствием этого является то, что в системе передачи сообщений нет проверки типов. Не гарантируется, что объект, которому направлено сообщение - получатель - ответит на сообщение, и если это не так, возникает исключение. [19]

Для отправки метода сообщения объекту, на который указывает указатель obj , потребуется следующий код на C ++ :

obj -> метод ( аргумент );

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

[ метод объекта  : аргумент ];

Вызов «метода» транслируется компилятором в семейство функций времени выполнения objc_msgSend (id self, SEL op, ...) . Различные реализации обрабатывают современные дополнения, такие как super . [20] В семействах GNU эта функция называется objc_msg_sendv , но она устарела в пользу современной системы поиска под objc_msg_lookup . [21]

Оба стиля программирования имеют свои сильные и слабые стороны. Объектно-ориентированное программирование в стиле Simula ( C ++ ) допускает множественное наследование и более быстрое выполнение за счет использования привязки времени компиляции, когда это возможно, но оно не поддерживает динамическое связывание по умолчанию. Это также заставляет все методы иметь соответствующую реализацию, если они не являются абстрактными.. Программирование в стиле Smalltalk, используемое в Objective-C, позволяет сообщениям оставаться нереализованными, а метод разрешается для его реализации во время выполнения. Например, сообщение может быть отправлено набору объектов, на которые ожидается ответ только от некоторых, не опасаясь возникновения ошибок времени выполнения. Передача сообщений также не требует, чтобы объект был определен во время компиляции. Для вызова метода в производном объекте по-прежнему требуется реализация. (См. Раздел о динамической типизации ниже, чтобы узнать больше о преимуществах динамического (позднего) связывания.)

Интерфейсы и реализации [ править ]

Objective-C требует, чтобы интерфейс и реализация класса находились в отдельно объявленных блоках кода. По соглашению разработчики помещают интерфейс в файл заголовка, а реализацию - в файл кода. Файлы заголовков, обычно с суффиксом .h, похожи на файлы заголовков C, в то время как файлы реализации (методов), обычно с суффиксом .m, могут быть очень похожи на файлы кода C.

Интерфейс [ править ]

Это аналогично объявлениям классов, используемым в других объектно-ориентированных языках, таких как C ++ или Python.

Интерфейс класса обычно определяется в файле заголовка. Распространенным соглашением является наименование файла заголовка после имени класса, например Ball.h будет содержать интерфейс для класса Ball .

Объявление интерфейса принимает форму:

@interface  classname  : superclassname  {  // переменные экземпляра } +  classMethod1 ; +  ( Возвращаемый_тип ) classMethod2 ; +  ( Возвращаемый_тип ) classMethod3: ( param1_type ) param1_varName ;-  ( return_type ) instanceMethod1With1Parameter: ( param1_type ) param1_varName ; -  ( return_type ) instanceMethod2With2Parameters: ( param1_type ) param1_varName  param2_callName: ( param2_type ) param2_varName ; @конец

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

Приведенный выше код примерно эквивалентен следующему интерфейсу C ++ :

class  classname  :  public  superclassname  { protected :  // переменные экземпляраpublic :  // Классовые (статические) функции  static  void  * classMethod1 ();  статическая  возвращаемый_тип  classMethod2 ();  статическая  возвращаемый_тип  classMethod3 ( param1_type  param1_varName ); // Экземпляр (член) функции  return_type  instanceMethod1With1Parameter ( param1_type  param1_varName );  return_type  instanceMethod2With2Parameters ( param1_type  param1_varName ,  param2_type  param2_varName  =  default ); };

Обратите внимание, что instanceMethod2With2Parameters: param2_callName: демонстрирует чередование сегментов селектора с выражениями аргументов, для которых нет прямого эквивалента в C / C ++.

Типы возврата могут быть любым стандартным типом C , указателем на универсальный объект Objective-C, указателем на объект определенного типа, например NSArray *, NSImage * или NSString *, или указателем на класс, к которому принадлежит метод. (тип экземпляра). Тип возврата по умолчанию - это общий идентификатор типа Objective-C .

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

-  ( void ) setRangeStart: ( int ) start  end: ( int ) end ; -  ( void ) importDocumentWithName: ( NSString  * ) имя  withSpecifiedPreferences: ( Preferences  * ) prefs  beforePage: ( int ) insertPage ;

Производным от определения интерфейса является категория , которая позволяет добавлять методы к существующим классам. [22]

Реализация [ править ]

Интерфейс объявляет только интерфейс класса, а не сами методы: фактический код записывается в файле реализации. Файлы реализации (методов) обычно имеют расширение файла .m, которое изначально означало «сообщения». [23]

@implementation  имя_класса +  ( возвращаемый_тип ) classMethod  {  // реализация } -  ( возвращаемый_тип ) instanceMethod  {  // реализация } @end

Методы написаны с использованием деклараций их интерфейсов. Сравнение Objective-C и C:

-  ( int ) метод: ( int ) i  {  return  [ self  square_root : i ]; }
int  функция ( int  я )  {  вернуть  квадрат_корень ( я ); }

Синтаксис допускает псевдонимы аргументов .

-  ( void ) changeColorToRed: ( float ) red  green: ( float ) green  blue: ( float ) blue  {  // ... Реализация ... }// Вызывается так: [ myColor  changeColorToRed : 5.0  green : 2.0  blue : 6.0 ];

Внутренние представления метода различаются между различными реализациями Objective-C. Если myColor относится к классу Color , метод экземпляра -changeColorToRed: green: blue: может иметь внутреннюю метку _i_Color_changeColorToRed_green_blue . Я должен ссылаться на метод экземпляра, с именами методов класса , а затем и прилагаемых двоеточием измененных подчеркивания. Поскольку порядок параметров является частью имени метода, его нельзя изменить в соответствии со стилем кодирования или выражением, как с истинно именованными параметрами.

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

Создание [ править ]

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

Создание экземпляра со стандартным инициализатором без параметров:

MyObject  * foo  =  [[ MyObject  alloc ]  инициализация ];

Создание экземпляра с помощью настраиваемого инициализатора:

MyObject  * foo  =  [[ MyObject  alloc ]  initWithString : myString ];

В случае, когда пользовательская инициализация не выполняется, вместо сообщений alloc-init часто можно использовать "новый" метод:

MyObject  * foo  =  [ MyObject  новый ];

Кроме того, некоторые классы реализуют инициализаторы методов класса. Мол +new, они сочетаются +allocи -init, но в отличие от +newних, возвращают автоматически выпущенный экземпляр. Некоторые инициализаторы методов класса принимают параметры:

MyObject  * foo  =  [ объект MyObject  ]; MyObject * bar = [ MyObject objectWithString : @ "Википедия :)" ];    

Alloc выделяет сообщение достаточно памяти для хранения всех переменных экземпляра для объекта, устанавливает все переменные экземпляра нулевые значения, и превращает память в экземпляр класса; ни в какой момент во время инициализации память не является экземпляром суперкласса.

Сообщение инициализации выполняет настройку экземпляра при создании. Метод инициализации часто записывается следующим образом:

-  ( id ) init  {  self  =  [ super  init ];  if  ( self )  {  // здесь выполняем инициализацию объекта  }  return  self ; }

Обратите внимание на idвозвращаемый тип в приведенном выше примере . Этот тип означает «указатель на любой объект» в Objective-C (см. Раздел « Динамическая типизация »).

Шаблон инициализатора используется, чтобы гарантировать, что объект правильно инициализирован его суперклассом до того, как метод init выполнит свою инициализацию. Он выполняет следующие действия:

  1. self = [супер инициализация]
    Посылает экземпляру суперкласса сообщение инициализации и присваивает результат self (указатель на текущий объект).
  2. если (сам)
    Проверяет, действителен ли возвращенный указатель на объект перед выполнением любой инициализации.
  3. вернуть себя
    Возвращает значение self вызывающей стороне.

Недействительный указатель на объект имеет значение nil ; условные операторы, такие как «if», обрабатывают nil как нулевой указатель, поэтому код инициализации не будет выполнен, если [super init] вернет nil. Если есть ошибка при инициализации, метод init должен выполнить любую необходимую очистку, включая отправку сообщения «release» самому себе, и вернуть nil, чтобы указать, что инициализация не удалась. Любая проверка на наличие таких ошибок должна выполняться только после вызова инициализации суперкласса, чтобы гарантировать, что уничтожение объекта будет выполнено правильно.

Если класс имеет более одного метода инициализации, только один из них («назначенный инициализатор») должен следовать этому шаблону; другие должны вызывать назначенный инициализатор вместо инициализатора суперкласса.

Протоколы [ править ]

В других языках программирования они называются «интерфейсами».

Objective-C был расширен в NeXT, чтобы представить концепцию множественного наследования спецификации, но не реализации, путем введения протоколов . Это шаблон, достижимый либо как абстрактный множественный унаследованный базовый класс в C ++ , либо как «интерфейс» (как в Java и C # ). Objective-C использует специальные протоколы, называемые неформальными протоколами, и протоколы, поддерживаемые компилятором, называемые формальными протоколами .

Неформальный протокол - это список методов, которые класс может реализовать. Это указано в документации, так как в языке его нет. Неформальные протоколы реализованы как категория (см. Ниже) в NSObject и часто включают необязательные методы, которые, если они реализованы, могут изменить поведение класса. Например, у класса текстового поля может быть делегат , реализующий неформальный протокол с дополнительным методом для выполнения автозаполнения вводимого пользователем текста. Текстовое поле определяет, реализует ли делегат этот метод (через отражение ), и, если да, вызывает метод делегата для поддержки функции автозаполнения.

Формальный протокол похож на интерфейс в Java, C # и Ada 2005 . Это список методов, которые любой класс может объявить для реализации. Версии Objective-C до 2.0 требовали, чтобы класс реализовал все методы в протоколе, который он объявляет как принимающий; компилятор выдаст ошибку, если класс не реализует все методы из своих объявленных протоколов. В Objective-C 2.0 добавлена ​​поддержка пометки определенных методов в протоколе как необязательных, и компилятор не будет обеспечивать реализацию необязательных методов.

Чтобы было сказано, что он соответствует этому протоколу, должен быть объявлен класс для реализации этого протокола. Это можно обнаружить во время выполнения. Формальные протоколы не могут предоставить никаких реализаций; они просто гарантируют вызывающим абонентам, что классы, соответствующие протоколу, предоставят реализации. В библиотеке NeXT / Apple протоколы часто используются системой распределенных объектов для представления возможностей выполнения объекта в удаленной системе.

Синтаксис

@protocol  NSLocking -  ( недействительная ) блокировка ; -  ( недействительная ) разблокировка ; @конец

означает, что существует абстрактная идея блокировки. Заявив в определении класса, что протокол реализован,

@interface  NSLock  : NSObject  < NSLocking > // ... @end

экземпляры NSLock утверждают, что они предоставят реализацию для двух методов экземпляра.

Динамический ввод [ править ]

Objective-C, как и Smalltalk, может использовать динамическую типизацию : объекту может быть отправлено сообщение, не указанное в его интерфейсе. Это может обеспечить повышенную гибкость, поскольку позволяет объекту «захватить» сообщение и отправить сообщение другому объекту, который может ответить на сообщение соответствующим образом, или аналогичным образом отправить сообщение другому объекту. Такое поведение известно как пересылка сообщений или делегирование (см. Ниже). В качестве альтернативы можно использовать обработчик ошибок, если сообщение не может быть переслано. Если объект не пересылает сообщение, не отвечает на него или не обрабатывает ошибку, система сгенерирует исключение времени выполнения. [24] Если сообщения отправлены на ноль (указатель на нулевой объект), они будут игнорироваться или вызывать общее исключение, в зависимости от параметров компилятора.

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

-  ( void ) setMyValue: ( id ) foo ;

В приведенном выше утверждении foo может относиться к любому классу.

-  ( void ) setMyValue: ( id < NSCopying > ) foo ;

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

-  ( void ) setMyValue: ( NSNumber  * ) foo ;

В приведенном выше утверждении foo должен быть экземпляром класса NSNumber .

-  ( void ) setMyValue: ( NSNumber < NSCopying >  * ) foo ;

В приведенном выше заявлении foo должен быть экземпляром класса NSNumber и соответствовать NSCopyingпротоколу.

В Objective-C все объекты представлены как указатели, и статическая инициализация не разрешена. Самый простой объект - это тип, на который указывает id ( objc_obj * ), который имеет только указатель isa, описывающий его класс. Другие типы из C, такие как значения и структуры, не изменились, потому что они не являются частью объектной системы. Это решение отличается от объектной модели C ++, где объединены структуры и классы.

Пересылка [ править ]

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

Среда выполнения Objective-C определяет пару методов в Object

  • методы пересылки:
    -  ( retval_t ) вперед: ( SEL ) sel  args: ( arglist_t ) args ;  // с GCC -  ( id ) forward: ( SEL ) sel  args: ( marg_list ) args ;  // с системами NeXT / Apple
  • методы действия:
    -  ( retval_t ) performv: ( SEL ) sel  args: ( arglist_t ) args ;  // с GCC -  ( id ) performv: ( SEL ) sel  args: ( marg_list ) args ;  // с системами NeXT / Apple

Объекту, желающему реализовать пересылку, нужно только переопределить метод пересылки новым методом для определения поведения пересылки. Метод действия performv :: не нужно переопределять, поскольку этот метод просто выполняет действие на основе селектора и аргументов. Обратите внимание на тип, который является типом сообщений в Objective-C.SEL

Примечание: в OpenStep, Cocoa и GNUstep, обычно используемых фреймворках Objective-C, класс Object не используется . - (Недействительными) forwardInvocation: (NSInvocation *) anInvocation метод NSObject класса используется , чтобы сделать переадресацию.

Пример [ править ]

Вот пример программы, демонстрирующей основы пересылки.

Forwarder.h
#import <objc / Object.h>@interface  Forwarder  : объект  {  идентификатор  получателя ;  // Объект, которому мы хотим переслать сообщение. }// Методы доступа. -  ( id ) получатель ; -  ( id ) setRecipient: ( id ) _recipient ; @конец
Экспедитор.m
#import "Forwarder.h"@implementation  Forwarder -  ( retval_t ) forward: ( SEL ) sel  args: ( arglist_t ) args  {  / *  * Проверяет, действительно ли получатель отвечает на сообщение.  * Это может быть или нежелательно, например, если получатель  * в свою очередь не отвечает на сообщение, он может выполнить пересылку  * самостоятельно.  * /  if  ([ recipient  RespondsToSelector : sel ])  {  return  [ recipient  performv : sel  args: args ];  }  else  {  return  [ собственная  ошибка : «Получатель не отвечает» ];  } }-  ( id ) setRecipient: ( id ) _recipient  {  [ автозапуск получателя  ]; получатель = [ _recipient удержать ]; вернуть себя ; }      -  ( id ) получатель  {  получатель возврата  ; } @end
Recipient.h
#import <objc / Object.h>// Простой объект Recipient. @interface  Получатель  : Объект -  ( id ) привет ; @конец
Recipient.m
#import "Recipient.h"@implementation  Recipient-  ( id ) hello  {  printf ( "Получатель передает привет! \ n " ); вернуть  себя ; }@конец
main.m
#import "Forwarder.h" #import "Recipient.h"int  main ( void )  {  Пересылка  * forwarder  =  [ Пересылка  новая ];  Получатель  * получатель  =  [ Получатель  новый ]; [ Форвардер  setRecipient : получатель ];  // Устанавливаем получателя.  / *  * Сервер пересылки наблюдения не отвечает на приветственное сообщение! Он будет  * переадресован. Все нераспознанные методы будут перенаправлены  * получателю  * (если получатель ответит им, как написано в Forwarder)  * /  [ forwarder  hello ]; [ выпуск получателя  ]; [ Форвардер выпуск ];   возврат  0 ; }

Заметки [ править ]

При компиляции с использованием gcc компилятор сообщает:

$ gcc -x objective-c -Wno-import Forwarder.m Recipient.m main.m -lobjcmain.m: В функции `main ':main.m: 12: предупреждение: `Forwarder 'не отвечает на` hello'$

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

$ ./a.outПолучатель передает привет!

Категории [ править ]

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

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

При запуске программы методы внутри категорий становятся неотличимы от методов класса. Категория имеет полный доступ ко всем переменным экземпляра в классе, включая частные переменные.

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

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

Языки C # и Visual Basic.NET реализуют внешне похожие функции в форме методов расширения , но у них отсутствует доступ к закрытым переменным класса. [26] Ruby и некоторые другие языки динамического программирования называют эту технику « исправлением обезьяны ».

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

Пример использования категорий [ править ]

В этом примере создается класс Integer путем определения сначала базового класса с реализованными только методами доступа и добавления двух категорий, арифметики и отображения , которые расширяют базовый класс. Хотя категории могут получать доступ к закрытым членам данных базового класса, часто хорошей практикой является доступ к этим закрытым членам данных с помощью методов доступа, которые помогают сохранять категории более независимыми от базового класса. Реализация таких средств доступа - одно из типичных применений категорий. Другой - использовать категории для добавления методов к базовому классу. Однако использование категорий для переопределения подкласса не считается хорошей практикой, также известной как исправление обезьян.. Неформальные протоколы реализованы как категория на базовом классе NSObject . По соглашению файлы, содержащие категории, расширяющие базовые классы, будут называться BaseClass + ExtensionClass.h .

Integer.h
#import <objc / Object.h>@interface  Integer  : объект  {  int  integer ; }-  ( int ) целое число ; -  ( id ) целое число: ( int ) _integer ; @конец
Integer.m
#import "Integer.h"@implementation  Integer -  ( int )  целое  {  return  integer ; }-  ( id )  целое число:  ( int )  _integer  {  integer  =  _integer ;  вернуть  себя ; } @end
Целое число + Arithmetic.h
#import "Integer.h"@interface  Integer  (Арифметика) -  ( id )  add:  ( Integer  * )  addend ; -  ( id )  sub:  ( Integer  * )  вычитать ; @конец
Целое число + Арифметика. M
# import "Integer + Arithmetic.h"@implementation  Integer  (Арифметика) -  ( id )  add:  ( Integer  * )  addend  {  return  [ self  integer :  [ self  integer ]  +  [ addend  integer ]]; }-  ( id )  sub:  ( Integer  * )  subtrahend  {  return  [ self  integer :  [ self  integer ]  -  [ вычесть  целое ]]; } @end
Целое число + Display.h
#import "Integer.h"@interface  Integer  (Дисплей) -  ( id )  showstars ; -  ( id )  showint ; @конец
Целое число + Display.m
# import "Integer + Display.h"@implementation  Целое число  (дисплей) -  ( ID )  showstars  {  INT  я ,  х  =  [ само  целое число ];  для  ( я  =  0 ;  я  <  х ;  я ++ )  {  printf ( "*" );  }  printf ( " \ п " ); вернуть  себя ; }-  ( ID )  showint  {  Printf ( "% d \ п " ,  [ само  целое число ]); вернуть  себя ; } @end
main.m
#import "Integer.h" #import "Integer + Arithmetic.h" #import "Integer + Display.h"int  main ( void )  {  целое число  * num1  =  [ целое  новое ],  * num2  =  [ целое  новое ];  int  x ; printf ( "Введите целое число:" );  scanf ( "% d" ,  & x ); [ num1  целое : x ];  [ Num1  showstars ]; printf ( "Введите целое число:" );  scanf ( "% d" ,  & x ); [ num2  целое : x ];  [ num2  showstars ]; [ число1  добавить : число2 ];  [ Num1  showint ]; возврат  0 ; }

Заметки [ править ]

Компиляция выполняется, например, следующими способами:

gcc -x objective-c main.m Integer.m Integer + Arithmetic.m Integer + Display.m -lobjc

Можно поэкспериментировать, исключив строки #import "Integer + Arithmetic.h" и [num1 add: num2] и исключив Integer + Arithmetic.m при компиляции. Программа по-прежнему будет работать. Это означает, что при необходимости можно смешивать и сопоставлять добавленные категории; если у категории не обязательно должна быть какая-то способность, ее просто нельзя скомпилировать.

Позирует [ править ]

Objective-C позволяет классу полностью заменить другой класс в программе. Говорят, что замещающий класс «изображает» целевой класс.

Создание классов было объявлено устаревшим в Mac OS X v10.5 и недоступно в 64-разрядной среде выполнения. Подобная функциональность может быть достигнута с помощью смены методов в категориях, при которой реализация одного метода заменяется другой, имеющей такую ​​же сигнатуру.

Для версий, все еще поддерживающих позирование, все сообщения, отправленные в целевой класс, вместо этого принимаются классом позирования. Есть несколько ограничений:

  • Класс может изображать только один из своих прямых или косвенных суперклассов.
  • Позирующий класс не должен определять какие-либо новые переменные экземпляра, которые отсутствуют в целевом классе (хотя он может определять или переопределять методы).
  • Целевой класс мог не получать никаких сообщений до позирования.

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

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

Например,

@interface  CustomNSApplication  : NSApplication @end@implementation  CustomNSApplication -  ( void )  setMainMenu:  ( NSMenu * )  menu  {  // что-то делаем с меню } @endclass_poseAs  ([ Класс CustomNSApplication  ], [ Класс NSApplication ]);  

Это перехватывает каждый вызов setMainMenu для NSApplication.

#import [ редактировать ]

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

Компиляция Linux gcc [ править ]

// ФАЙЛ: hello.m #import <Foundation / Foundation.h> int  main  ( int  argc ,  const  char  *  argv []) {  / * моя первая программа на Objective-C * /  NSLog ( @ "Hello, World! \ n " );  возврат  0 ; }
# Компиляция командной строки для компилятора gcc и MinGW:
$ gcc \  $ ( gnustep-config --objc-flags )  \ -o hello \ hello.m \ -L / GNUstep / System / Library / Libraries \ -lobjc \ -lgnustep-base$ ./hello

Другие особенности [ править ]

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

  • Делегирование методов другим объектам и удаленный вызов можно легко реализовать с помощью категорий и пересылки сообщений.
  • Swizzling от Isa указателя позволяет классы изменять во время выполнения. Обычно используется для отладки, когда освобожденные объекты превращаются в зомби-объекты, единственная цель которых - сообщить об ошибке, когда кто-то их вызывает. Swizzling также использовался в Enterprise Objects Framework для создания ошибок базы данных. [ необходима цитата ] Swizzling сегодня используется Apple Foundation Framework для реализации Key-Value Observing .

Варианты языка [ править ]

Objective-C ++ [ править ]

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

  • Класс C ++ не может быть производным от класса Objective-C и наоборот.
  • Пространства имен C ++ нельзя объявлять внутри объявления Objective-C.
  • Объявления Objective-C могут появляться только в глобальной области, а не внутри пространства имен C ++.
  • Классы Objective-C не могут иметь переменные экземпляра классов C ++, у которых отсутствует конструктор по умолчанию или у которых есть один или несколько виртуальных методов, [ необходима цитата ], но указатели на объекты C ++ могут использоваться в качестве переменных экземпляра без ограничений (выделите их с помощью new в - init метод).
  • Семантика C ++ "по значению" не может быть применена к объектам Objective-C, которые доступны только через указатели.
  • Объявление Objective-C не может находиться в объявлении шаблона C ++ и наоборот. Однако типы Objective-C (например, Classname *) могут использоваться как параметры шаблона C ++.
  • Обработка исключений Objective-C и C ++ отличается; обработчики каждого из них не могут обрабатывать исключения другого типа. В результате деструкторы объекта не запускаются. Это смягчается в недавних средах выполнения «Objective-C 2.0», поскольку исключения Objective-C либо полностью заменяются исключениями C ++ (среда выполнения Apple), либо частично, когда библиотека Objective-C ++ связана (GNUstep libobjc2). [27]
  • Блоки Objective-C и лямбда-выражения C ++ 11 - разные сущности. Однако блок прозрачно генерируется в macOS при передаче лямбда-выражения там, где ожидается блок. [28]

Objective-C 2.0 [ править ]

На Всемирной конференции разработчиков 2006 года Apple объявила о выпуске «Objective-C 2.0», версии языка Objective-C, включающей «современную сборку мусора, улучшения синтаксиса, [29] улучшения производительности во время выполнения [30] и 64- битовая поддержка ". Mac OS X v10.5 , выпущенная в октябре 2007 года, включала компилятор Objective-C 2.0. GCC 4.6 поддерживает множество новых функций Objective-C, таких как объявленные и синтезированные свойства, точечный синтаксис, быстрое перечисление, дополнительные методы протокола, атрибуты метода / протокола / класса, расширения классов и новый API времени выполнения GNU Objective-C. [31]

Название Objective-C 2.0 представляет собой прорыв в системе управления версиями языка, поскольку последней версией Objective-C для NeXT была "objc4". [32] Это имя проекта было сохранено в последнем выпуске устаревшего исходного кода среды выполнения Objective-C в Mac OS X Leopard (10.5). [33]

Сборка мусора [ править ]

Objective-C 2.0 предоставил необязательный консервативный сборщик мусора для поколений . При запуске в режиме обратной совместимости среда выполнения превратила операции подсчета ссылок, такие как «сохранить» и «освободить», в запретные операции . Когда сборка мусора была включена, все объекты подлежали сборке мусора. Обычные указатели C могут быть квалифицированы с помощью "__strong", чтобы также инициировать перехват базового компилятора барьера записи и, таким образом, участвовать в сборке мусора. [34] Также была предоставлена ​​слабая подсистема обнуления, такая, что указатели, помеченные как «__weak», устанавливаются в ноль при сборе объекта (или, проще говоря, памяти GC). Сборщик мусора не существует в реализации Objective-C 2 для iOS.0.[35] Сборка мусора в Objective-C выполняется в фоновом потоке с низким приоритетом и может останавливаться при пользовательских событиях, чтобы пользователь оставался отзывчивым. [36]

Сборка мусора устарела в Mac OS X v10.8 в пользу автоматического подсчета ссылок (ARC). [37] Objective-C на iOS 7, работающей на ARM64, использует 19 бит из 64-битного слова для хранения счетчика ссылок в виде помеченных указателей . [38] [39]

Свойства [ править ]

Objective-C 2.0 представляет новый синтаксис для объявления переменных экземпляра как свойств с дополнительными атрибутами для настройки генерации методов доступа. Свойства в некотором смысле являются общедоступными переменными экземпляра; то есть объявление переменной экземпляра как свойства предоставляет внешним классам доступ (возможно, ограниченный, например только для чтения) к этому свойству. Свойство может быть объявлено как «только для чтения» и может быть обеспечено семантикой хранения, такой как assign, copyили retain. По умолчанию учитываются свойства atomic, что приводит к блокировке, предотвращающей одновременный доступ к ним нескольких потоков. Свойство можно объявить как nonatomic, что снимает эту блокировку.

@interface  Person  : NSObject  { @public  NSString  * название ; @private  int  age ; }@property ( копия )  NSString  * имя ; @property (только чтение )  int  age ;-  ( id ) initWithAge: ( int ) возраст ; @конец

Свойства реализуются посредством @synthesizeключевого слова, которое генерирует методы получения (и установки, если не только для чтения) в соответствии с объявлением свойства. В качестве альтернативы методы получения и установки должны быть реализованы явно, или @dynamicможно использовать ключевое слово, чтобы указать, что методы доступа будут предоставлены другими средствами. При компиляции с использованием clang 3.1 или выше все свойства, которые явно не объявлены @dynamic, отмечены readonlyили имеют полные реализованные пользователем средства получения и установки, будут автоматически неявно неявно @synthesize'd.

@implementation  Person @synthesize  имя ;-  ( id ) initWithAge: ( int ) initAge  {  self  =  [ super  init ];  if  ( self )  {  // ПРИМЕЧАНИЕ: прямое присвоение переменной экземпляра, а не  средство установки свойства age  =  initAge ;  }  return  self ; }-  ( int ) age  {  возраст возвращения  ; } @end

Доступ к свойствам можно получить, используя традиционный синтаксис передачи сообщений, точечную нотацию или, в кодировании значения ключа, по имени с помощью методов "valueForKey:" / "setValue: forKey:".

Человек  * aPerson  =  [[ Человек  Alloc ]  initWithAge : 53 ]; Лицо . name  =  @ "Стив" ;  // ПРИМЕЧАНИЕ: точечная запись, используется синтезированный установщик,  // эквивалент [aPerson setName: @ "Steve"]; NSLog ( @ "Доступ сообщения (% @), точечная нотация (% @), имя свойства (% @) и  прямой  экземпляр  переменного  доступ ( %  @)  ",  [ aPerson  имя ],  aPerson . Имя ,  [ aPerson  valueForKey: @ "name" ],  aPerson  ->  name );

Чтобы использовать точечную нотацию для вызова средств доступа к свойствам в методе экземпляра, следует использовать ключевое слово "self":

-  ( void ) enterMyselfWithProperties : ( BOOL ) useGetter  {  NSLog ( @ "Привет, меня зовут% @." ,  ( useGetter  ?  self . name  :  name ));  // ПРИМЕЧАНИЕ: доступ getter vs. ivar }

Свойства класса или протокола могут подвергаться динамическому анализу .

int  i ; int  propertyCount  =  0 ; objc_property_t  * propertyList  =  class_copyPropertyList ([ класс персоны  ], & propertyCount ); для  ( я  =  0 ;  я  <  propertyCount ;  я ++ )  {  objc_property_t  * thisProperty  =  propertyList  +  i ;  const  char  * propertyName  =  property_getName ( * thisProperty );  NSLog ( @ "У человека есть свойство: '% s'" ,  propertyName ); }

Неустойчивые переменные экземпляра [ править ]

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

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

Быстрое перечисление [ править ]

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

// Использование NSEnumerator NSEnumerator  * enumerator  =  [ thePeople  objectEnumerator ]; Человек  * p ;while  (( p  =  [ перечислитель  nextObject ])  ! =  nil )  {  NSLog ( @ "% @ is% i лет." ,  [ p  name ],  [ p  age ]); }
// Использование индексов для  ( int  i  =  0 ;  i  <  [ thePeople  count ];  i ++ )  {  Person  * p  =  [ thePeople  objectAtIndex : i ];  NSLog ( @ "% @% i лет." ,  [ P  name ],  [ p  age ]); }
// Использование быстрого перечисления для  ( Person  * p  in  thePeople )  {  NSLog ( @ "% @ is% i years old." ,  [ P  name ],  [ p  age ]); }

Быстрое перечисление генерирует более эффективный код, чем стандартное перечисление, поскольку вызовы методов для перечисления объектов заменяются арифметикой указателя с использованием протокола NSFastEnumeration. [40]

Расширения класса [ править ]

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

Последствия для развития Какао [ править ]

Все приложения Objective-C, разработанные для macOS, которые используют вышеуказанные улучшения для Objective-C 2.0, несовместимы со всеми операционными системами до 10.5 (Leopard). Поскольку быстрое перечисление не создает точно такие же двоичные файлы, как стандартное перечисление, его использование приведет к сбою приложения в Mac OS X версии 10.4 или более ранней.

Блокирует [ править ]

Блоки - нестандартное расширение для Objective-C (а также C и C ++ ), которое использует специальный синтаксис для создания замыканий . Блоки поддерживаются только в Mac OS X 10.6 «Snow Leopard» или новее, iOS 4 или новее, а также GNUstep с libobjc2 1.7 и компиляцией с clang 3.1 или новее. [42]

#include  <stdio.h>#include  <Block.h>typedef  int  ( ^ IntBlock ) ();IntBlock  MakeCounter ( int  start ,  int  increment )  { __block  int  i  =  start ;return  Block_copy (  ^  { int  ret  =  i ; i  + =  приращение ; return  ret ; });}int  main ( void )  { IntBlock  mycounter  =  MakeCounter ( 5 ,  2 ); printf ( "Первый вызов:% d \ n " ,  mycounter ()); printf ( "Второй вызов:% d \ n " ,  mycounter ()); printf ( "Третий вызов:% d \ n " ,  mycounter ());/ * поскольку он был скопирован, его также необходимо освободить * / Block_release ( mycounter );возврат  0 ; } / * Вывод: Первый вызов: 5 Второй вызов: 7 Третий вызов: 9 * /

Современный Objective-C [ править ]

Apple со временем добавила некоторые дополнительные функции в Objective 2.0. Дополнения относятся только к « компилятору Apple LLVM », то есть к языку clang frontend. Как ни странно, управление версиями, используемое Apple, отличается от восходящего потока LLVM; обратитесь к версиям Xcode § Toolchain для перевода на номера версий LLVM с открытым исходным кодом. [43]

Автоматический подсчет ссылок [ править ]

Автоматический подсчет ссылок (ARC) - это функция времени компиляции, которая избавляет программистов от необходимости вручную управлять подсчетом сохраненных ссылок с помощью retainи release. [44] В отличие от сборки мусора , которая происходит во время выполнения, ARC устраняет накладные расходы отдельного процесса, управляющего счетчиками сохраненных данных. ARC и ручное управление памятью не исключают друг друга; программисты могут продолжать использовать код без ARC в проектах с поддержкой ARC, отключив ARC для отдельных файлов кода. Xcode также может попытаться автоматически обновить проект до ARC.

ARC был представлен в LLVM 3.0. Это переводится в Xcode 4.2 (2011) или компилятор Apple LLVM 3.0. [45]

Литералы [ править ]

Среды выполнения NeXT и Apple Obj-C уже давно включают краткий способ создания новых строк с использованием буквального синтаксиса @"a new string"или перехода к константам CoreFoundation kCFBooleanTrueи kCFBooleanFalseдля NSNumberс логическими значениями. Использование этого формата избавляет программиста от необходимости использовать более длинные initWithStringили похожие методы при выполнении определенных операций.

При использовании Apple , LLVM компилятор 4.0 (Xcode 4.4) или более поздней версии, массивы, словари и числа ( NSArray, NSDictionary, NSNumberклассы) также могут быть созданы с помощью синтаксиса литерала вместо методов. [46] (Компилятор Apple LLVM 4.0 переводится в LLVM с открытым исходным кодом и Clang 3.1.) [47]

Пример без литералов:

NSArray  * myArray  =  [ NSArray  arrayWithObjects : объект1 , объект2 , объект3 , ноль ]; NSDictionary  * myDictionary1  =  [ NSDictionary  dictionaryWithObject : someObject  forKey : @ "key" ]; NSDictionary  * myDictionary2  =  [ NSDictionary  dictionaryWithObjectsAndKeys : object1 ,  key1 ,  object2 ,  key2 ,  nil]; NSNumber  * myNumber  =  [ NSNumber  numberWithInt : myInt ]; NSNumber  * mySumNumber =  [ NSNumber  numberWithInt :( 2  +  3 )]; NSNumber  * myBoolNumber  =  [ NSNumber  numberWithBool : ДА ];

Пример с литералами:

NSArray  * myArray  =  @ [  объект1 ,  объект2 ,  объект3  ] ; NSDictionary  * myDictionary1  =  @ {  @ "key"  :  someObject  } ; NSDictionary  * myDictionary2  =  @ {  key1 :  object1 ,  key2 :  object2  } ; NSNumber  * myNumber  =  @ ( myInt ) ; NSNumber  * mySumNumber  =  @ ( 2+ 3 ) ; NSNumber  * myBoolNumber  =  @YES ; NSNumber  * myIntegerNumber  =  @ 8 ;

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

Подписка [ править ]

При использовании компилятора Apple LLVM 4.0 или более поздней версии массивами и словарями ( NSArrayи NSDictionaryклассами) можно управлять с помощью индексации. [46] Индексы могут использоваться для извлечения значений из индексов (массив) или ключей (словарь), а с изменяемыми объектами также могут использоваться для установки объектов в индексы или ключи. В коде индекс обозначается скобками [ ]. [48]

Пример без индекса:

id  object1  =  [ someArray  objectAtIndex : 0 ]; id  object2  =  [ someDictionary  objectForKey : @ "ключ" ]; [ someMutableArray  replaceObjectAtIndex : 0  withObject : object3 ]; [ someMutableDictionary  setObject : object4  forKey : @ "ключ" ];

Пример с индексами:

id  object1  =  someArray [ 0 ]; id  object2  =  someDictionary [ @ "ключ" ]; someMutableArray [ 0 ]  =  объект3 ; someMutableDictionary [ @ "ключ" ]  =  объект4 ;

"Современный" синтаксис Objective-C (1997) [ править ]

После покупки NeXT компанией Apple были предприняты попытки сделать этот язык более приемлемым для программистов, более знакомых с Java, чем Smalltalk. Одна из этих попыток заключалась в том, чтобы ввести то, что в то время называли «современным синтаксисом» для Objective-C [49] (в отличие от текущего «классического» синтаксиса). Поведение не изменилось, это был просто альтернативный синтаксис. Вместо того, чтобы писать вызов метода, например

 объект  =  [[ MyClass  alloc ]  инициализация ];  [ объект  firstLabel :  param1  secondLabel :  param2 ];

Вместо этого он был написан как

 объект  =  ( MyClass . alloc ). init ;  объект . метки  (  param1 ,  param2  );

Аналогичным образом декларации пошли из формы

 - ( void )  firstLabel :  ( int ) param1  secondLabel :  ( int ) param2 ;

к

 - ( void )  метки  (  int  param1 ,  int  param2  );

Этот «современный» синтаксис больше не поддерживается в текущих диалектах языка Objective-C.

mulle-objc [ править ]

Проект mulle-objc - это еще одна повторная реализация Objective-C. Он поддерживает компиляторы GCC или Clang / LLVM в качестве бэкэндов. Он отличается от других сред выполнения с точки зрения синтаксиса, семантики и совместимости с ABI. Он поддерживает Linux, FreeBSD и Windows.

Компилятор переносимых объектов [ править ]

Помимо реализации GCC / NeXT / Apple , которая добавила несколько расширений к исходной реализации Stepstone , существует еще одна бесплатная реализация Objective-C с открытым исходным кодом, называемая Portable Object Compiler. [50] Набор расширений, реализуемых Portable Object Compiler, отличается от реализации GCC / NeXT / Apple; в частности, он включает блоки, подобные Smalltalk, для Objective-C, хотя в нем отсутствуют протоколы и категории - две функции, широко используемые в OpenStep, его производных и родственниках. В целом, POC представляет собой более старую, предшествующую NeXT стадию развития языка, примерно соответствующую книге Брэда Кокса 1991 года.

Он также включает библиотеку времени выполнения под названием ObjectPak, которая основана на исходной библиотеке Cox ICPak101 (которая, в свою очередь, является производной от библиотеки классов Smalltalk-80) и радикально отличается от OpenStep FoundationKit.

GEOS Objective-C [ править ]

В системе PC GEOS использовался язык программирования, известный как GEOS Objective-C или goc ; [51] Несмотря на схожесть названий, эти два языка похожи только в общей концепции и использовании ключевых слов с префиксом @.

Clang [ править ]

Набор компиляторов Clang , часть проекта LLVM , реализует Objective-C и другие языки. После того, как GCC 4.3 (2008) перешел на GPLv3, Apple отказалась от него в пользу clang, компилятора, который он имеет больше юридических полномочий для модификации. В результате многие функции современного языка Objective-C поддерживаются только Clang.

Схема управления версиями Apple для своего основанного на clang "компилятора LLVM" отличается от системы управления версиями LLVM с открытым исходным кодом. См. Перевод в Xcode § Toolchain [43]

GNU, GNUstep и WinObjC [ править ]

Проект GNU долгое время интересовался платформой для переноса программ NeXT и Obj-C. Журнал изменений для каталога libobjc в GCC предполагает, что он существовал до 1998 года (GCC 2.95), а его README также указывает на перезапись в 1993 году (GCC 2.4). [52]

Исходный код внешнего интерфейса NeXT был выпущен, так как он был создан как часть GCC, выпустила публичную лицензию GNU, которая вынуждает тех, кто создает производные работы, делать это. [ когда? ] Apple продолжила эту традицию, выпустив форк GCC до версии 4.2.1, после чего отказались от компилятора. Сопровождающие GCC приняли изменения, но не вложили много средств в поддержку новых функций, таких как язык Objective-C 2.0. [32] ( Какой компилятор )

Разработчики GNUstep, заинтересованные в новом языке, в 2009 году разделили GCC libobjc на независимый от GCC проект под названием libobjc2 . Они также организовали использование среды выполнения с Clang, чтобы воспользоваться преимуществами нового синтаксиса языка. [32] ( Какой компилятор ) GCC в то же время продвигался медленно, но в GCC 4.6.0 (2011) они также перешли на Objective-C 2.0 в своей libobjc. [31] [53] Документация GNUstep предполагает, что в реализации GCC все еще отсутствует поддержка блоков, нефункциональных переменных и более новой версии ARC. [32] ( Какая среда выполнения )

Microsoft раздвоенной libobjc2 в часть WinObjC , мост IOS для универсальной платформы Windows , в 2015 году в сочетании с его собственной реализацией Cocoa Touch и базовыми интерфейсами, проект предоставляет возможность повторного использования кода IOS приложения внутри UWP приложений. [54]

В Windows инструменты разработки Objective-C доступны для загрузки на веб-сайте GNUStep. Система разработки GNUStep состоит из следующих пакетов: GNUstep MSYS System, GNUstep Core, GNUstep Devel, GNUstep Cairo, ProjectCenter IDE (как Xcode, но не такой сложный), Gorm (Interface Builder Like Xcode NIB builder). Эти бинарные установщики не обновлялись с 2016 года [55], поэтому было бы лучше просто установить их, собрав вместо этого Cygwin или MSYS2 .

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

Objective-C сегодня часто используется в тандеме с фиксированной библиотекой стандартных объектов (часто называемой «комплектом» или «фреймворком»), такой как Cocoa , GNUstep или ObjFW . Эти библиотеки часто поставляются с операционной системой: библиотеки GNUstep часто поставляются с Linux.на основе дистрибутивов, а Cocoa поставляется с macOS. Программист не обязан наследовать функциональность существующего базового класса (NSObject / OFObject). Objective-C позволяет объявлять новые корневые классы, которые не наследуют никаких существующих функций. Первоначально среды программирования на основе Objective-C обычно предлагали класс Object в качестве базового класса, от которого унаследованы почти все остальные классы. С введением OpenStep NeXT создал новый базовый класс с именем NSObject, который предлагал дополнительные функции по сравнению с Object (например, упор на использование ссылок на объекты и подсчет ссылок вместо необработанных указателей). Почти все классы в Какао наследуются от NSObject.

Переименование не только помогло дифференцировать новое поведение классов по умолчанию в OpenStep API, но и позволило коду, который использовал Object - исходный базовый класс, используемый в NeXTSTEP (и, более или менее, в других библиотеках классов Objective-C), - в сосуществуют в одной среде выполнения с кодом, который использовал NSObject (с некоторыми ограничениями). Введение двухбуквенного префикса также стало упрощенной формой пространств имен, чего не хватает в Objective-C. Использование префикса для создания неформального идентификатора упаковки стало неформальным стандартом кодирования в сообществе Objective-C и продолжается по сей день.

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

Анализ языка [ править ]

Реализации Objective-C используют тонкую систему времени выполнения, написанную на C [ необходима цитата ] , что немного увеличивает размер приложения. Напротив, большинство объектно-ориентированных систем в то время, когда они были созданы, использовали большие виртуальные машины.время выполнения. Программы, написанные на Objective-C, как правило, не намного больше, чем размер их кода и библиотек (которые, как правило, не нужно включать в дистрибутив программного обеспечения), в отличие от систем Smalltalk, в которых был большой объем памяти. раньше просто открывал окно. Приложения Objective-C, как правило, больше, чем аналогичные приложения C или C ++, потому что динамическая типизация Objective-C не позволяет вырезать или встраивать методы. Поскольку у программиста есть такая свобода делегировать, пересылать вызовы, создавать селекторы на лету и передавать их системе времени выполнения, компилятор Objective-C не может предположить, что можно безопасно удалить неиспользуемые методы или встроенные вызовы.

Точно так же язык может быть реализован поверх существующих компиляторов C (в GCC сначала как препроцессор, затем как модуль), а не как новый компилятор. Это позволяет Objective-C использовать огромную существующую коллекцию кода C, библиотек, инструментов и т. Д. Существующие библиотеки C могут быть заключены в оболочки Objective-C для обеспечения интерфейса в стиле объектно-ориентированного программирования. В этом аспекте он похож на библиотеку GObject и язык Vala , которые широко используются при разработке приложений GTK .

Все эти практические изменения снизили барьер для входа, что , вероятно, стало самой большой проблемой для широкого распространения Smalltalk в 1980-х.

Распространенная критика заключается в том, что Objective-C не поддерживает языковую поддержку пространств имен . Вместо этого программисты вынуждены добавлять префиксы к именам своих классов, которые традиционно короче имен пространств имен и, следовательно, более подвержены конфликтам. Начиная с 2007 года, все классы и функции macOS в среде программирования Какао имеют префикс «NS» (например, NSObject, NSButton), чтобы идентифицировать их как принадлежащие ядру macOS или iOS; «NS» происходит от имен классов, определенных во время разработки NeXTSTEP .

Поскольку Objective-C является строгим надмножеством C, он не рассматривает примитивные типы C как объекты первого класса .

В отличие от C ++ , Objective-C не поддерживает перегрузку операторов . Также, в отличие от C ++, Objective-C позволяет объекту напрямую наследовать только от одного класса (запрещая множественное наследование ). Однако в большинстве случаев категории и протоколы могут использоваться как альтернативные способы достижения тех же результатов.

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

Управление памятью [ править ]

Первые версии Objective-C не поддерживали сборку мусора . В то время это решение было предметом споров, и многие люди считали, что долгие «мертвые времена» (когда Smalltalk выполнял сбор данных) сделали всю систему непригодной для использования. Некоторые сторонние реализации добавили эту функцию (в первую очередь GNUstep с использованием Boehm ), и Apple реализовала ее в Mac OS X v10.5 . [56] Однако в более поздних версиях macOS и iOS сборка мусора не рекомендуется в пользу автоматического подсчета ссылок (ARC), представленного в 2011 году.

С помощью ARC компилятор автоматически вставляет вызовы сохранения и освобождения в код Objective-C на основе статического анализа кода . Автоматизация избавляет программиста от необходимости писать код управления памятью. ARC также добавляет слабые ссылки на язык Objective-C. [57]

Философские различия между Objective-C и C ++ [ править ]

Дизайн и реализация C ++ и Objective-C представляют принципиально разные подходы к расширению C.

В дополнение к стилю процедурного программирования C, C ++ напрямую поддерживает определенные формы объектно-ориентированного программирования , общего программирования и метапрограммирования . C ++ также поставляется с большой стандартной библиотекой, которая включает несколько контейнерных классов . Точно так же Objective-C добавляет объектно-ориентированное программирование , динамическую типизацию и отражение в C. Objective-C не предоставляет стандартную библиотеку как таковую , но в большинстве мест, где используется Objective-C, он используется с OpenStep- подобным. библиотека, такая как OPENSTEP , Cocoa или GNUstep, который обеспечивает функциональность, аналогичную стандартной библиотеке C ++.

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

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

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

См. Также [ править ]

  • C (язык программирования)
  • C ++
  • Сравнение языков программирования
  • Сравнение с COM, GObject, SOM, Windows Runtime, XPCOM
  • Быстрый
  • Xcode
  • WinObjC (также известный как Microsoft Bridge для iOS)

Ссылки [ править ]

  1. ^ «Версии среды выполнения и платформы» . Developer.apple.com . Архивировано 20 июля 2016 года . Проверено 24 декабря 2017 года .
  2. ^ Lattner, Крис (3 июня 2014). "Домашняя страница Криса Латтнера" . Крис Латтнер. Архивировано 4 июня 2014 года . Проверено 3 июня 2014 года . Язык Swift - продукт неустанных усилий команды лингвистических экспертов, гуру документации, ниндзя по оптимизации компиляторов и невероятно важной внутренней группы экспертов, которые предоставили отзывы, чтобы помочь усовершенствовать и протестировать идеи в боевых условиях. Конечно, он также очень выиграл от опыта, с трудом завоеванного многими другими языками в этой области, черпая идеи из Objective-C, Rust, Haskell, Ruby, Python, C #, CLU и слишком многих других, чтобы перечислить.
  3. ^ «Фреймворки приложений» . Яблоко. Июнь 2014. Архивировано 16 февраля 2019 года . Проверено 13 февраля 2019 года .
  4. ^ Сингх, Амит (декабрь 2003 г.). «Краткая история Mac OS X» . Mac OS X Внутреннее устройство. Архивировано 14 мая 2012 года . Проверено 11 июня 2012 года .
  5. ^ Garling, Калеб. «Язык программирования iPhone стал третьим по популярности в мире» . Проводной . Архивировано 9 сентября 2013 года . Проверено 20 мая 2013 года .
  6. ^ Вентк, Ричард (2009). Какао: Том 5 Справочника разработчиков Apple Developer Series . Джон Вили и сыновья. ISBN 978-0-470-49589-6. Архивировано 16 февраля 2017 года . Проверено 22 июля, 2016 .
  7. ^ Бьянкуцци, Федерико; Уорден, Шейн (2009). Идеи программирования . O'Reilly Media, Inc., стр. 242–246. ISBN 978-0-596-51517-1. Архивировано 17 февраля 2017 года . Проверено 22 июля, 2016 .
  8. ^ Кокс, Брэд (1983). «Объектно-ориентированный прекомпилятор: программирование методов Smalltalk 80 на языке C» . Уведомления ACM SIGPLAN . Нью-Йорк, штат Нью-Йорк: ACM . 18 (1). DOI : 10.1145 / 948093.948095 . S2CID 6975032 . Проверено 17 февраля 2011 года . 
  9. ^ "Common Lisp и Readline" . Архивировано 6 сентября 2014 года . Проверено 15 сентября 2014 года .Проблема впервые возникла, когда NeXT предложила распространить модифицированный GCC на две части и позволить пользователю связывать их. Джобс спросил меня, законно ли это. В то время мне казалось, что это так, следуя рассуждениям вроде того, что вы используете; но так как результат был очень нежелательным для свободных программ, я сказал, что мне нужно спросить юриста. То, что сказал адвокат, меня удивило; он сказал, что судьи сочтут такие схемы «уловками» и будут очень жестко к ним относиться. Он сказал, что судья спросит, действительно ли это одна программа, а не как она обозначена. Поэтому я вернулся к Джобсу и сказал, что, по нашему мнению, его план не разрешен GPL. Прямым результатом этого является то, что теперь у нас есть интерфейс для Objective C.Они хотели распространить синтаксический анализатор Objective C как отдельный закрытый пакет для связи с серверной частью GCC, но, поскольку я не согласился, что это разрешено, они сделали его бесплатным.
  10. ^ «GNUstep: Введение» . Разработчики GNUstep / Проект GNU. Архивировано 6 августа 2012 года . Проверено 29 июля 2012 года .
  11. ^ «Крестен Краб Торуп | LinkedIn» . www.linkedin.com . Архивировано 15 июля 2014 года . Проверено 23 июня 2016 года .
  12. ^ "Написать код Objective-C" . apple.com. 23 апреля 2013 года. Архивировано 24 декабря 2013 года . Проверено 22 декабря 2013 года .
  13. ^ "Учебный лагерь Objective-C" . Архивировано 11 февраля 2018 года . Проверено 11 февраля 2018 года . Objective-C - это строгий надмножество ANSI C
  14. ^ "Исследование Objective-C" . Архивировано 4 сентября 2014 года . Проверено 4 сентября 2014 года . Objective-C - это объектно-ориентированное строгое надмножество C
  15. Рианна Ли, Кейт (3 сентября 2013 г.). Pro Objective-C . Апресс. ISBN 9781430250500. Архивировано 14 мая 2018 года . Проверено 24 декабря 2017 г. - через Google Книги.
  16. ^ «Теги для заголовков Objective-C» . Архивировано 1 апреля 2017 года . Проверено 11 февраля 2018 года . Objective-C - это надмножество C
  17. ^ «Теперь доступен AppScan Source 8.7» . Архивировано 3 февраля 2017 года . Проверено 11 февраля 2018 года . Язык программирования Objective-C - это надмножество языка программирования C.
  18. Apple, Inc. (19 октября 2009 г.). «Разрешение динамического метода» . Руководство по программированию во время выполнения Objective-C . Архивировано 7 сентября 2010 года . Проверено 25 ноября 2014 года .
  19. Apple, Inc. (19 октября 2009 г.). «Как избежать ошибок обмена сообщениями» . Язык программирования Objective-C . Архивировано из оригинала 8 сентября 2010 года.
  20. ^ "objc_msgSend - Среда выполнения Objective-C" . Документация для разработчиков Apple . Проверено 10 февраля 2020 года .
  21. ^ «Обмен сообщениями со средой выполнения GNU Objective-C» . Использование коллекции компиляторов GNU (GCC) . Проверено 10 февраля 2020 года .
  22. ^ "Категория" . Разработчик Apple (компетенции ядра какао) .
  23. ^ Дэлримпл, Марк; Кнастер, Скотт (27 июня 2012 г.). Изучите Objective-C на Mac . п. 9. ISBN 9781430241881. Расширение .m первоначально обозначало «сообщения», когда впервые был представлен Objective-C, имея в виду центральную особенность Objective-C.
  24. ^ "Руководство по программированию во время выполнения Objective-C" . Apple Inc. Архивировано 4 апреля 2014 года . Проверено 21 октября 2013 года .
  25. ^ "ACM SIGGRAPH 1983 Выпуск 8 - Smalltalk" . Архивировано из оригинального 15 апреля 2009 года . Проверено 7 октября 2008 года .
  26. ^ «Методы расширения (Руководство по программированию на C #)» . Microsoft. Октябрь 2010. Архивировано 11 июля 2011 года . Проверено 10 июля 2011 года .
  27. ^ «Использование C ++ с Objective-C» . Mac OS X Reference Library . Архивировано из оригинального 5 сентября 2010 года . Проверено 10 февраля 2010 года .
  28. ^ «Расширения языка Clang - документация Clang 3.5» . Clang.llvm.org. Архивировано 24 февраля 2014 года . Проверено 16 апреля 2014 года .
  29. ^ «Objective-C 2.0: больше подсказок» . Lists.apple.com. 10 августа 2006 года Архивировано из оригинала 18 июня 2009 года . Проверено 30 мая 2010 года .
  30. ^ "Re: Objective-C 2.0" . Lists.apple.com. Архивировано из оригинального 24 ноября 2010 года . Проверено 30 мая 2010 года .
  31. ^ a b «Серия выпусков GCC 4.6 - Изменения, новые функции и исправления: Проект GNU: Фонд свободного программного обеспечения» . Gcc.gnu.org . Архивировано 5 января 2018 года . Проверено 24 декабря 2017 года .
  32. ^ a b c d "Часто задаваемые вопросы по ObjC2" . GNUstep . Проверено 6 января 2020 года .
  33. ^ "Браузер исходного кода: objc4, 756.2" . Открытый исходный код Apple . Проверено 6 января 2020 года .
  34. ^ Руководство по программированию сборки мусора: API сборки мусора. Архивировано 5 июня 2012 г. на WebCite (веб-сайт разработчика Apple - поиск по запросу «__strong»).
  35. ^ «Руководство по программированию сборки мусора: Введение в сборку мусора» . Apple , Inc. 3 октября 2011 года архивации с оригинала на 5 июня 2012 года . Проверено 23 декабря 2011 года .
  36. ^ «Серия технологий Leopard для разработчиков: Обзор Objective-C 2.0» . Apple , Inc. 6 ноября, 2007. Архивировано из оригинала 24 июля 2010 года . Проверено 30 мая 2010 года .
  37. ^ «Переход к примечаниям к выпуску ARC» . Корпорация Apple 17 июля 2012 года архивации с оригинала на 5 июня 2012 года . Проверено 26 августа 2012 года .
  38. ^ Майк Эш. «Пятничные вопросы и ответы 2013-09-27: ARM64 и вы» . mikeash.com. Архивировано 26 апреля 2014 года . Проверено 27 апреля 2014 года .
  39. ^ "Hamster Emporium: [объяснение объекта]: isa без указателя" . Sealiesoftware.com. 24 сентября 2013 года. Архивировано 3 июня 2014 года . Проверено 27 апреля 2014 года .
  40. ^ Apple, Inc. (2009). «Быстрый перебор» . apple.com. Архивировано 17 декабря 2009 года . Проверено 31 декабря 2009 года .
  41. ^ Free Software Foundation, Inc. (2011). «Серия выпусков GCC 4.6 - Изменения, новые функции и исправления» . Gcc.gnu.org . Архивировано 2 декабря 2013 года . Проверено 27 ноября 2013 года .
  42. ^ «Темы программирования блоков - Библиотека разработчика Mac» . Apple , Inc. 8 марта 2011 года архивации с оригинала на 5 июня 2012 года . Проверено 28 ноября 2012 года .
  43. ^ a b «Автоматический подсчет ссылок (ARC) Objective-C - документация Clang 11» . Документация Clang . Проверено 20 февраля 2020 года . На данный момент имеет смысл редактировать этот документ выпусками его единственной реализации (и основного проекта) clang. «LLVM XY» относится к выпуску clang с открытым исходным кодом из проекта LLVM. «Apple XY» относится к предоставленной Apple версии компилятора Apple LLVM.
  44. ^ «Переход к ARC» . Apple Inc. Архивировано 7 сентября 2011 года . Проверено 8 октября 2012 года .
  45. ^ «Примечания к выпуску LLVM 3.0» . releases.llvm.org .
  46. ^ a b «Программирование с помощью Objective-C: значения и коллекции» . Apple Inc. Архивировано 7 сентября 2011 года . Проверено 8 октября 2012 года .
  47. ^ «Примечания к выпуску Clang 3.1» . releases.llvm.org .
  48. ^ "Objective-C Literals - документация Clang 3.5" . Clang.llvm.org. Архивировано 6 июня 2014 года . Проверено 16 апреля 2014 года .
  49. ^ Руководство разработчика Rhapsody , AP Professional, 1997, стр. 76-84
  50. ^ "Компилятор переносимых объектов" . Users.pandora.be. 1 января 1970 года. Архивировано 2 августа 2008 года . Проверено 30 мая 2010 года .
  51. ^ "Домашняя страница Breadbox Computer Company LLC" . Архивировано из оригинального 27 июля 2011 года . Проверено 8 декабря 2010 года .
  52. ^ "gcc / libobjc" . GitHub . gcc-зеркало. 6 января 2020 . Проверено 6 января 2020 года . среда выполнения была полностью переписана в gcc 2.4. Более ранняя среда выполнения содержала несколько серьезных ошибок и была довольно неполной.
  53. ^ "API среды выполнения GNU Objective-C" . Используя GCC . Проверено 6 января 2020 года .
  54. ^ "WinObjC на GitHub" . Архивировано 2 декабря 2017 года . Проверено 13 февраля 2018 года .
  55. ^ "Установщик GNUStep" . Архивировано 17 февраля 2018 года . Проверено 14 февраля 2018 года .
  56. Apple, Inc. (22 августа 2006 г.). «Mac OS X Leopard - Xcode 3.0» . apple.com. Архивировано из оригинального 24 -го октября 2007 года . Проверено 22 августа 2006 года .
  57. ^ «Переход к примечаниям к выпуску ARC» . Библиотека разработчика iOS . Developer.apple.com. Архивировано 7 сентября 2011 года . Проверено 16 апреля 2014 года .

Дальнейшее чтение [ править ]

  • Кокс, Брэд Дж. (1991). Объектно-ориентированное программирование: эволюционный подход . Эддисон Уэсли. ISBN 0-201-54834-8.

Внешние ссылки [ править ]

  • Программирование с помощью Objective-C от Apple (2012-12-13)
  • Язык программирования Objective-C от Apple (11.10.2011)
  • Руководство по программированию времени выполнения Objective-C от Apple (19.10.2009)
  • Руководство по программированию на Objective-C GNUstep Base
  • Objective-C Брэда Кокса
  • Objective-C FAQ