Jump to content

Цель-C

(Перенаправлено из Objective-C 2.0 )

Цель-C
Семья С
Разработано Том Лав и Брэд Кокс
Впервые появился 1984 год ; 40 лет назад ( 1984 )
Стабильная версия
2.0 [1]
Дисциплина набора текста Статический , динамичный , слабый
ТЫ Кросс-платформенный
Расширения имен файлов .ч, .м, .мм, .М
Веб-сайт developer.apple.com
Основные реализации
Кланг , GCC
Под влиянием
С , Смолток
Под влиянием
Groovy , Java , Nu , Objective-J , TOM , Swift [2]

Objective-C — это высокоуровневый общего назначения объектно - ориентированный язык программирования , который добавляет Smalltalk . в стиле обмен сообщениями к языку C [3] язык программирования. Первоначально разработанный Брэдом Коксом и Томом Лавом в начале 1980-х годов, он был выбран NeXT для своей NeXTSTEP операционной системы . Благодаря Apple macOS от NeXTSTEP, прямому происхождению [4] Objective-C был стандартным языком программирования, который использовался, поддерживался и продвигался Apple для разработки приложений macOS и iOS (через соответствующие API-интерфейсы Cocoa и Cocoa Touch ) до появления языка программирования Swift в 2014 году. [3]

Программы Objective-C, разработанные для операционных систем сторонних производителей или не зависящие от API Apple, также могут быть скомпилированы для любой платформы, поддерживаемой GNU GCC или LLVM / Clang .

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

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

Накануне создания своей компании оба познакомились со Smalltalk в 1981 году в Центре технологий программирования корпорации ITT. Самая ранняя работа над Objective-C относится примерно к этому времени. [6] Кокс был заинтригован проблемами истинного повторного использования в разработке и программировании программного обеспечения. Он понял, что такой язык, как Smalltalk, будет иметь неоценимое значение при создании сред разработки для системных разработчиков в ITT. Однако он и Том Лав также признали, что обратная совместимость с C имеет решающее значение в сфере телекоммуникационной инженерии ITT. [7]

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

Лав и Кокс в конечном итоге сформировали PPI для коммерциализации своего продукта, который объединил компилятор Objective-C с библиотеками классов. В 1986 году Кокс опубликовал основное описание Objective-C в его первоначальном виде в книге Object-Oriented Programming, An Evolutionary Approach . Хотя он осторожно отметил, что проблема повторного использования заключается не только в том, что обеспечивает 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, реализующий его: ИМП . [18] Следствием этого является то, что система передачи сообщений не имеет проверки типов. Объект, которому направляется сообщение — получатель , не гарантирует, что ответит на сообщение, а если нет, то он вызывает исключение. [19]

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

obj->method(argument);

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

[obj method:argument];

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

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

Интерфейсы и реализации

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

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

Интерфейс

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

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

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

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

@interface classname : superclassname {
  // instance variables
}
+ classMethod1;
+ (return_type)classMethod2;
+ (return_type)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;
@end

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

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

class classname : public superclassname {
protected:
  // instance variables

public:
  // Class (static) functions
  static void *classMethod1();
  static return_type classMethod2();
  static return_type classMethod3(param1_type param1_varName);

  // Instance (member) functions
  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 *)name
      withSpecifiedPreferences:(Preferences *)prefs
                    beforePage:(int)insertPage;

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

Выполнение

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

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

@implementation classname
+ (return_type)classMethod {
  // implementation
}
- (return_type)instanceMethod {
  // implementation
}
@end

Методы пишутся с использованием объявлений их интерфейсов. Сравнение Objective-C и C:

- (int)method:(int)i {
  return [self square_root:i];
}
int function(int i) {
  return square_root(i);
}

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

- (void)changeColorToRed:(float)red green:(float)green blue:(float)blue {
  //... Implementation ...
}

// Called like so:
[myColor changeColorToRed:5.0 green:2.0 blue:6.0];

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

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

Создание экземпляра

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

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

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

MyObject *foo = [[MyObject alloc] init];

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

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

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

MyObject *foo = [MyObject new];

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

MyObject *foo = [MyObject object];
MyObject *bar = [MyObject objectWithString:@"Wikipedia :)"];

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

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

- (id)init {
    self = [super init];
    if (self) {
        // perform initialization of object here
    }
    return self;
}

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

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

  • Линия 2
    Отправляет экземпляру суперкласса инициализирующее сообщение и присваивает результат self (указатель на текущий объект).
  • Линия 3
    Проверяет, действителен ли возвращаемый указатель объекта, прежде чем выполнять какую-либо инициализацию.
  • Линия 6
    Возвращает значение self вызывающей стороне.

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

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

Протоколы

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

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

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
- (void)lock;
- (void)unlock;
@end

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

@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 все объекты представлены как указатели, и статическая инициализация не допускается. Самый простой объект — это тип, который идентификатор ( objc_obj * ), который имеет только указатель isa , описывающий его класс. Другие типы из C, такие как значения и структуры, не изменяются, поскольку они не являются частью объектной системы. Это решение отличается от объектной модели C++, где структуры и классы объединены.

Пересылка

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

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

Среда выполнения Objective-C определяет пару методов в Объект

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

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

Примечание. В OpenStep, Cocoa и GNUstep, широко используемых средах Objective-C, не используется Класс объекта . - (void)forwardInvocation:(NSInvocation *)anInvocation метод Класс NSObject используется для пересылки.

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

Форвардер.h
#import <objc/Object.h>

@interface Forwarder : Object {
  id recipient; // The object we want to forward the message to.
}

// Accessor methods.
- (id)recipient;
- (id)setRecipient:(id)_recipient;
@end
Форвардер.м
#import "Forwarder.h"

@implementation Forwarder
- (retval_t)forward:(SEL)sel args:(arglist_t)args {
  /*
  * Check whether the recipient actually responds to the message.
  * This may or may not be desirable, for example, if a recipient
  * in turn does not respond to the message, it might do forwarding
  * itself.
  */
  if ([recipient respondsToSelector:sel]) {
    return [recipient performv:sel args:args];
  } else {
    return [self error:"Recipient does not respond"];
  }
}

- (id)setRecipient:(id)_recipient {
  [recipient autorelease];
  recipient = [_recipient retain];
  return self;
}

- (id)recipient {
  return recipient;
}
@end
Получатель.h
#import <objc/Object.h>

// A simple Recipient object.
@interface Recipient : Object
- (id)hello;
@end
Получатель.м
#import "Recipient.h"

@implementation Recipient

- (id)hello {
  printf("Recipient says hello!\n");

  return self;
}

@end
main.m
#import "Forwarder.h"
#import "Recipient.h"

int main(void) {
  Forwarder *forwarder = [Forwarder new];
  Recipient *recipient = [Recipient new];

  [forwarder setRecipient:recipient]; // Set the recipient.
  /*
  * Observe forwarder does not respond to a hello message! It will
  * be forwarded. All unrecognized methods will be forwarded to
  * the recipient
  * (if the recipient responds to them, as written in the Forwarder)
  */
  [forwarder hello];

  [recipient release];
  [forwarder release];

  return 0;
}

Примечания

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

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

$ gcc -x objective-c -Wno-import Forwarder.m Recipient.m main.m -lobjc
main.m: In function `main':
main.m:12: warning: `Forwarder' does not respond to `hello'
$

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

$ ./a.out
Recipient says hello!

Категории

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

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

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

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

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

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

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

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

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

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

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

Целое число.h
#import <objc/Object.h>

@interface Integer : Object {
  int integer;
}

- (int)integer;
- (id)integer:(int)_integer;
@end
Целое число.м
#import "Integer.h"

@implementation Integer
- (int) integer {
  return integer;
}

- (id) integer: (int) _integer {
  integer = _integer;
  return self;
}
@end
Целое число+Арифметика.h
#import "Integer.h"

@interface Integer (Arithmetic)
- (id) add: (Integer *) addend;
- (id) sub: (Integer *) subtrahend;
@end
Целое число+Арифметика.м
#import "Integer+Arithmetic.h"

@implementation Integer (Arithmetic)
- (id) add: (Integer *) addend {
  return [self integer: [self integer] + [addend integer]];
}

- (id) sub: (Integer *) subtrahend {
  return [self integer: [self integer] - [subtrahend integer]];
}
@end
Целое число+Display.h
#import "Integer.h"

@interface Integer (Display)
- (id) showstars;
- (id) showint;
@end
Целое число+Display.m
# import "Integer+Display.h"

@implementation Integer (Display)
- (id) showstars {
  int i, x = [self integer];
  for (i = 0; i < x; i++) {
    printf("*");
  }
  printf("\n");

  return self;
}

- (id) showint {
  printf("%d\n", [self integer]);

  return self;
}
@end
main.m
#import "Integer.h"
#import "Integer+Arithmetic.h"
#import "Integer+Display.h"

int main(void) {
  Integer *num1 = [Integer new], *num2 = [Integer new];
  int x;

  printf("Enter an integer: ");
  scanf("%d", &x);

  [num1 integer:x];
  [num1 showstars];

  printf("Enter an integer: ");
  scanf("%d", &x);

  [num2 integer:x];
  [num2 showstars];

  [num1 add:num2];
  [num1 showint];

  return 0;
}

Примечания

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

Компиляцию выполняют, например:

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

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

позирует

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

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

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

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

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

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

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

Например,

@interface CustomNSApplication : NSApplication
@end

@implementation CustomNSApplication
- (void) setMainMenu: (NSMenu*) menu {
  // do something with menu
}
@end

class_poseAs ([CustomNSApplication class], [NSApplication class]);

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

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

GCC-компиляция Linux

[ редактировать ]
// FILE: hello.m
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
    /* my first program in Objective-C */
    NSLog(@"Hello, World! \n");
    return 0;
}
$ # Compile Command Line for gcc and MinGW Compiler:
$ gcc \
    $(gnustep-config --objc-flags) \
    -o hello \
    hello.m \
    -L /GNUstep/System/Library/Libraries \
    -lobjc \
    -lgnustep-base

$ ./hello

Другие особенности

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

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

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

Языковые варианты

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

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]

На Всемирной конференции разработчиков 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). Сборщик мусора не существует в реализации iOS Objective-C 2.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 *name;
@private
  int age;
}

@property(copy) NSString *name;
@property(readonly) int age;

- (id)initWithAge:(int)age;
@end

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

@implementation Person
@synthesize name;

- (id)initWithAge:(int)initAge {
  self = [super init];
  if (self) {
    // NOTE: direct instance variable assignment, not property setter
    age = initAge;
  }
  return self;
}

- (int)age {
  return age;
}
@end

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

Person *aPerson = [[Person alloc] initWithAge:53];
aPerson.name = @"Steve"; // NOTE: dot notation, uses synthesized setter,
                         // equivalent to [aPerson setName: @"Steve"];
NSLog(@"Access by message (%@), dot notation(%@), property name(% @) and "
       "direct instance variable access(% @) ",
              [aPerson name],
      aPerson.name, [aPerson valueForKey:@"name"], aPerson -> name);

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

- (void)introduceMyselfWithProperties:(BOOL)useGetter {
  NSLog(@"Hi, my name is %@.", (useGetter ? self.name : name));
  // NOTE: getter vs. ivar access
}

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

int i;
int propertyCount = 0;
objc_property_t *propertyList =
    class_copyPropertyList([aPerson class], &propertyCount);

for (i = 0; i < propertyCount; i++) {
  objc_property_t *thisProperty = propertyList + i;
  const char *propertyName = property_getName(*thisProperty);
  NSLog(@"Person has a property: '%s'", propertyName);
}

Нехрупкие переменные экземпляра

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

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

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

Быстрое перечисление

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

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

// Using NSEnumerator
NSEnumerator *enumerator = [thePeople objectEnumerator];
Person *p;

while ((p = [enumerator nextObject]) != nil) {
  NSLog(@"%@ is %i years old.", [p name], [p age]);
}
// Using indexes
for (int i = 0; i < [thePeople count]; i++) {
  Person *p = [thePeople objectAtIndex:i];
  NSLog(@"%@ is %i years old.", [p name], [p age]);
}
// Using fast enumeration
for (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 или более ранней.

Blocks — это нестандартное расширение для 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 += increment;
    return ret;
  });

}

int main(void) {
  IntBlock mycounter = MakeCounter(5, 2);
  printf("First call: %d\n", mycounter());
  printf("Second call: %d\n", mycounter());
  printf("Third call: %d\n", mycounter());

  /* because it was copied, it must also be released */
  Block_release(mycounter);

  return 0;
}
/* Output:
  First call: 5
  Second call: 7
  Third call: 9
*/

Современный Objective-C

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

Со временем Apple добавила в Objective 2.0 некоторые дополнительные функции. Дополнения касаются только «компилятора Apple LLVM », т.е. интерфейса clang языка. Как ни странно, управление версиями, используемое 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:object1,object2,object3,nil];
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:YES];

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

NSArray *myArray = @[ object1, object2, object3 ];
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:@"key"];
[someMutableArray replaceObjectAtIndex:0 withObject:object3];
[someMutableDictionary setObject:object4 forKey:@"key"];

Пример с подпиской:

id object1 = someArray[0];
id object2 = someDictionary[@"key"];
someMutableArray[0] = object3;
someMutableDictionary[@"key"] = object4;

«Современный» синтаксис Objective-C (1997 г.)

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

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

    object = [[MyClass alloc] init];
    [object firstLabel: param1 secondLabel: param2];

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

    object = (MyClass.alloc).init;
    object.labels ( param1, param2 );

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

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

к

    -(void) labels ( int param1, int param2 );

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

мне-объект

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

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

Портативный компилятор объектов

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

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

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

ГЕОС Цель-C

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

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

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

Схема управления версиями Apple для ее «компилятора LLVM» на основе clang отличается от системы управления версиями 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, заинтересованные в новом языке, создали форк GCC. libobjc в проект, независимый от GCC, под названием libobjc2 в 2009 году. Они также организовали использование среды выполнения с 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 и базовыми API проект позволяет повторно использовать код приложения iOS внутри приложений UWP. [54]

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

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

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

Objective-C сегодня часто используется в тандеме с фиксированной библиотекой стандартных объектов (часто известной как «набор» или «фреймворк»), такой как Cocoa , GNUstep или ObjFW . Эти библиотеки часто поставляются вместе с операционной системой: библиотеки GNUstep часто поставляются с дистрибутивами на базе Linux , а Cocoa — с macOS. Программист не обязан наследовать функциональность существующего базового класса (NSObject/OFObject). Objective-C позволяет объявлять новые корневые классы, которые не наследуют существующие функции. Первоначально среды программирования на основе Objective-C обычно предлагали класс Object в качестве базового класса, от которого наследовались почти все остальные классы. С появлением OpenStep компания NeXT создала новый базовый класс под названием NSObject, который предлагал дополнительные функции по сравнению с Object (например, акцент на использовании ссылок на объекты и подсчете ссылок вместо необработанных указателей). Почти все классы в Cocoa наследуются от 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, чтобы обеспечить интерфейс в стиле OO. В этом аспекте она похожа на библиотеку GObject и язык Vala , которые широко используются при разработке приложений GTK .

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

Распространенной критикой является то, что Objective-C не имеет языковой поддержки пространств имен . Вместо этого программисты вынуждены добавлять префиксы к именам своих классов, которые традиционно короче имен пространств имен и, следовательно, более подвержены коллизиям. С 2007 года все классы и функции macOS в среде программирования Cocoa имеют префикс «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 -подобной библиотекой. такую ​​библиотеку, как OENSTEP , 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 году.

См. также

[ редактировать ]
  1. ^ «Версии времени выполнения и платформы» . Разработчик.apple.com . Архивировано из оригинала 20 июля 2016 года . Проверено 24 декабря 2017 г.
  2. ^ Латтнер, Крис (3 июня 2014 г.). «Домашняя страница Криса Лэттнера» . Крис Лэттнер. Архивировано из оригинала 4 июня 2014 года . Проверено 3 июня 2014 г. Язык Swift — это продукт неустанных усилий команды языковых экспертов, гуру документации, ниндзя по оптимизации компиляторов и невероятно важной внутренней экспериментальной группы, которая предоставляла отзывы, помогающие совершенствовать и проверять идеи. Конечно, он также получил большую пользу от опыта, с трудом полученного многими другими языками в этой области, черпая идеи из Objective-C, Rust, Haskell, Ruby, Python, C#, CLU и многих других, чтобы их перечислять.
  3. ^ Jump up to: а б «Фреймворки приложений» . Яблоко. Июнь 2014. Архивировано из оригинала 16 февраля 2019 года . Проверено 13 февраля 2019 г.
  4. ^ Сингх, Амит (декабрь 2003 г.). «Краткая история Mac OS X» . Внутреннее устройство Mac OS X. Архивировано из оригинала 14 мая 2012 года . Проверено 11 июня 2012 г.
  5. ^ Гарлинг, Калеб. «Язык программирования iPhone стал третьим по популярности в мире» . Проводной . Архивировано из оригинала 9 сентября 2013 года . Проверено 20 мая 2013 г.
  6. ^ Венк, Ричард (2009). Какао: Том 5 справочника разработчиков Apple Developer Series . Джон Уайли и сыновья. ISBN  978-0-470-49589-6 . Архивировано из оригинала 16 февраля 2017 года . Проверено 22 июля 2016 г.
  7. ^ Бьянкуцци, Федерико; Надзиратель, Шейн (2009). Мастера программирования . О'Рейли Медиа, Инк. стр. 242–246. ISBN  978-0-596-51517-1 . Архивировано из оригинала 17 февраля 2017 года . Проверено 22 июля 2016 г.
  8. ^ Кокс, Брэд (1983). «Объектно-ориентированный прекомпилятор: программирование методов Smalltalk 80 на языке C» . Уведомления ACM SIGPLAN . 18 (1). Нью-Йорк, штат Нью-Йорк: ACM . дои : 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 г.). Про Объектив-С . Торопиться. 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 (основные компетенции Cocoa) .
  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#)» . Майкрософт. Октябрь 2010. Архивировано из оригинала 11 июля 2011 года . Проверено 10 июля 2011 г.
  27. ^ «Использование C++ с Objective-C» . Справочная библиотека Mac OS X. Архивировано из оригинала 5 сентября 2010 года . Проверено 10 февраля 2010 г.
  28. ^ «Расширения языка Clang — документация Clang 3.5» . Clang.llvm.org. Архивировано из оригинала 24 февраля 2014 года . Проверено 16 апреля 2014 г.
  29. ^ «Objective-C 2.0: больше подсказок» . Списки.apple.com. 10 августа 2006. Архивировано из оригинала 18 июня 2009 года . Проверено 30 мая 2010 г.
  30. ^ «Re: Objective-C 2.0» . Списки.apple.com. Архивировано из оригинала 24 ноября 2010 года . Проверено 30 мая 2010 г.
  31. ^ Jump up to: а б «Серия выпусков GCC 4.6 — изменения, новые функции и исправления: Проект GNU: Фонд свободного программного обеспечения» . Gcc.gnu.org . Архивировано из оригинала 5 января 2018 года . Проверено 24 декабря 2017 г.
  32. ^ Jump up to: а б с д «Часто задаваемые вопросы по ObjC2» . GNUшаг . Проверено 6 января 2020 г.
  33. ^ «Исходный браузер: objc4, 756.2» . Apple с открытым исходным кодом . Проверено 6 января 2020 г.
  34. ^ Руководство по программированию сбора мусора: API сбора мусора. Архивировано 9 июня 2012 г. на Wayback Machine (веб-сайт разработчика Apple — найдите «__strong»)
  35. ^ «Руководство по программированию сборки мусора: введение в сборку мусора» . Apple Inc., 3 октября 2011 г. Архивировано из оригинала 9 июня 2012 г. . Проверено 23 декабря 2011 г.
  36. ^ «Серия Leopard Technology для разработчиков: обзор Objective-C 2.0» . Apple Inc., 6 ноября 2007 г. Архивировано из оригинала 24 июля 2010 г. . Проверено 30 мая 2010 г.
  37. ^ «Переход на примечания к выпуску ARC» . Apple Inc., 17 июля 2012 г. Архивировано из оригинала 9 июня 2012 г. . Проверено 26 августа 2012 г.
  38. ^ Майк Эш. «Пятничные вопросы и ответы 27 сентября 2013 г.: 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. ^ Фонд свободного программного обеспечения, Inc. (2011). «Серия выпусков GCC 4.6 – изменения, новые функции и исправления» . Gcc.gnu.org . Архивировано из оригинала 2 декабря 2013 года . Проверено 27 ноября 2013 г.
  42. ^ «Темы по программированию блоков – Библиотека разработчиков Mac» . Apple Inc., 8 марта 2011 г. Архивировано из оригинала 9 июня 2012 г. . Проверено 28 ноября 2012 г.
  43. ^ Jump up to: а б «Автоматический подсчет ссылок Objective-C (ARC) — документация Clang 11» . Документация по Clang . Проверено 20 февраля 2020 г. На данный момент имеет смысл обновлять этот документ по выпускам его единственной реализации (и основного проекта) — clang. «LLVM XY» относится к выпуску clang с открытым исходным кодом из проекта LLVM. «Apple XY» относится к предоставленной Apple версии компилятора Apple LLVM.
  44. ^ «Переход в АРК» . Apple Inc. Архивировано из оригинала 7 сентября 2011 года . Проверено 8 октября 2012 г.
  45. ^ «Примечания к выпуску LLVM 3.0» . Releases.llvm.org .
  46. ^ Jump up to: а б «Программирование с использованием Objective-C: значения и коллекции» . Apple Inc. Архивировано из оригинала 7 сентября 2011 года . Проверено 8 октября 2012 г.
  47. ^ «Примечания к выпуску Clang 3.1» . Releases.llvm.org .
  48. ^ «Литералы Objective-C — документация Clang 3.5» . Clang.llvm.org. Архивировано из оригинала 6 июня 2014 года . Проверено 16 апреля 2014 г.
  49. ^ Руководство разработчика Rhapsody , AP Professional, 1997, стр. 76–84.
  50. ^ «Портативный компилятор объектов» . Пользователи.pandora.be. 1 января 1970 года. Архивировано из оригинала 2 августа 2008 года . Проверено 30 мая 2010 г.
  51. ^ «Домашняя страница ООО «Хлебная компьютерная компания»» . Архивировано из оригинала 27 июля 2011 года . Проверено 8 декабря 2010 г.
  52. ^ "gcc/libobjc" . Гитхаб . 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 . Разработчик.apple.com. Архивировано из оригинала 7 сентября 2011 года . Проверено 16 апреля 2014 г.

Дальнейшее чтение

[ редактировать ]
  • Кокс, Брэд Дж. (1991). Объектно-ориентированное программирование: эволюционный подход . Эддисон Уэсли. ISBN  0-201-54834-8 .
[ редактировать ]
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 2887f3525697e768d9eaed2c1db5a398__1721233260
URL1:https://arc.ask3.ru/arc/aa/28/98/2887f3525697e768d9eaed2c1db5a398.html
Заголовок, (Title) документа по адресу, URL1:
Objective-C - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)