Objective-C — это простой язык программирования, разработанный как язык объектно-ориентированного программирования. Objective-C расширяет стандартные возможности ANSI-C, осуществляя поддержку таких возможностей, как описание классов, методов и свойств. Синтаксис языка в основном основан на языке Smalltalk — одном из первых ООП-языков.

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

Если же вы не программировали раньше в языках ООП, тогда вам нужно усвоить некоторые базовые концепции, перед тем как приступить к разработке приложений. Использование объектов ООП является фундаментальным в работе приложений на iOS, и понимание их использования и взаимодействия между ними важны для программирования. Для того чтобы понять концепции ООП, изучите Object-Oriented Programming with Objective-C[1]. Вы также можете изучить Cocoa Fundamentals Guide[2] чтобы узнать о применении концепций ООП в Cocoa. Для более детального изучения синтаксиса языка Objective-C вы можете изучить The Objective-C 2.0 Programming Language[3].

Objective-C: Как надмножество C

Objective-C — это надмножество языка ANSI-C, в котором поддерживается некоторый базовый синтаксис C. Также как и в C-коде, вы определяете заголовочный (header) файл и файл кода (source) чтобы было проще отделить объявление от реализации в вашем коде программы. Заголовочные файлы в Objective-C используют расширение файлов, прдставленное в Таблице 1.

Таблица 1.  Расширения файлов для кода Objective-C

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

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

Строковые переменные

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

Класс NSString обеспечивает упаковку объекта для строк, которые имеют все необходимые преимущества, включая встроенное управление памятью для того, чтобы хранить строки произвольной длины, поддержку Unicode, утилит форматирования printf-стиля и т.п. Хотя обычно используются именно такие строки, Objective-C обеспечивает сокращенное обозначение для создания объекта NSString из значения константы. Чтобы использовать этот сокращенное обозначение все что вам нужно сделать — предопределить стандартную строку, заключенную в двойные кавычки с символом @, так как показано в примерах ниже:

Классы

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

Определение класса в Objective-C требует двух различных частей: интерфейса и реализации. Интерфейсная часть содержит объявление класса и определяет переменные экземпляра и методы, связанные с классом. Интерфейс, как правило, заносится в .h файлы. Реализация содержит фактический код для методов класса и, как правило, содержится в .m файлы.

Иллюстрация 1 показывает синтаксис, объявляющий класс по имени MyClass, который наследуется из базового класса NSObject. Декларация класса всегда начинается с директивы компилятора @interface и заканчивается директивой @end. После имени класса следует имя родительского класса, отделенное двоеточием. Переменные экземпляра класса объявляются в блоке кода, который заключен в скобки ({ и }). После блока описания переменных экземпляра следует список методов, объявляемых в классе. После каждого объявления переменной экземпляра или метода ставится точка с запятой.

Иллюстрация 1.  Объявление класса

image00

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

В следующем примере показаны строго и слабо типизированные переменных:

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

Методы и сообщения

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

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

Иллюстрация 2.  Синтаксис объявления метода

image01

Объявлению предшествуют знак минуса (-) , который указывает, что это метод экземпляра класса. Фактическое имя метода (insertObject:atIndex:) — это связь всех ключевых слов сигнатуры, включая символы двоеточия. Символы двоеточия объявляют присутствие параметра. Если у метода нет никаких параметров, то опустите двоеточие только после первого ключевого слова сигнатуры. В приведенном примере метод получает два параметра.

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

Сообщения заключаются в квадратные скобки [ и ]. Внутри скобок указывается объект, которому предназначено сообщение (включая все необходимые параметры) и само сообщение. Например, чтобы послать сообщение insertObject:atIndex: объекту из myArray переменной, следует использовать следующий синтаксис:

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

Objective-C также обеспечивает точечный синтаксис вызова . Методы доступа получают и устанавливают состояние объекта, и обычно принимают форму  -(type)propertyName и  -(void)setPropertyName:(type). Используя точечный синтаксис, вы можете переписать предыдущий пример следующим образом:

Вы также можете использовать точечный синтаксис для назначения:

Это просто другой синтаксис для записи, [myAppObject setTheArray:aNewArray];.

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

Обычно вы будете использовать методы класса, как фабричные методы для создания новых экземпляров класса или для доступа к некоторой части общей информации, связанной с классом. Синтаксис для объявления метода класса идентичен синтаксису объявления метода экземпляра, за одним исключением — вместо знака минус перед идентификатором типа метода, вы используете знак плюс (+).

The following example illustrates how you use a class method as a factory method for a class. In this case, the array method is a class method on the NSArray class—and inherited by NSMutableArray—that allocates and initializes a new instance of the class and returns it to your code.

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

Листинг 1 показывает реализацию класса MyClass из предыдущего примера. Как и объявление класса, реализация класса заключена между двумя директивами компилятора — @implementation и @end. Эти директивы предоставляют обзорную информацию, которая нужна компилятору для того, чтобы связать вложенные методы с соответствующим классом. Поэтому, объявление метода соответствует заданному объявлению в интерфейсе, кроме включения блока с кодом.

Листинг 1.  Реализация класса

 

Объявленные свойства

Свойства — удобное средство для замены объявления средств доступа метода (accessor method). Свойства не создают новые переменные экземпляра в объявленом класск. На самом деле, свойства — это упрощенный способ (shorthand) для определения методов, обращающихся к существующим переменным экземплярам. Классы, которые подставляют переменные экземпляра, могут использовать обозначение свойства вместо того, чтобы использовать синтаксис getter и setter. Классы также могут использовать свойства для того, чтобы подставить «виртуальные» переменные экземпляров  класса — данные вычисленные динамически, но фактически не сохраненые в переменных экземплярах класса.

 

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

 

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

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

Хотя имена объекта и свойства в предыдущем примере надуманы, они все же демонстрируют гибкость свойств. Синтаксис с применением точки фактически маскирует соответствующий набор вызовов метода. Каждое доступное для чтения свойство поддерживается методом с таким же именем, что и само свойство. Каждое доступное для записи свойство поддерживается дополнительным методом формы setPropertyName: , где имя свойства начинается с большой буквы. (Эти методы являются фактической реализация свойств и являются причиной, по которой вы можете включать объявления свойства для атрибутов вашего класса не поддерживаемых переменными экземпляра класса). Давайте перепишем предыдущий пример с использованием методов вместо свойств:

Для того чтобы узнать больше о том, как объявлять свойства в своих собственных классах, прочтите раздел «Properties» в документе The Objective-C 2.0 Programming Language[3].

 

Протоколы и Делегаты

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

 

В iPhone OS обычно протоколы используются для делегирования объектов. Делегированный объект — это объект, который действует от имени (или под руководством) другого объекта. Чтобы лучше понять как взаимодействуют между собой протоколы, делегаты и другие объекты, давайте рассмотрим пример.

 

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

 

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

В случае, когда используется много протоколов делегирования, принятие протокола — это просто вопрос реализации методов определенных этим протоколом. Есть некоторые протоколы, которые требуют, чтобы вы ясно заявили, что вы поддерживаете протокол, и тогда протоколы могут определять оба метода, как необходимые, так и опциональные. Чем глубже вы увлекаетесь разработкой приложений, тем больше времени вам придется потратить на то, чтобы почитать раздел «Protocols» из документа The Objective-C 2.0 Programming Language[3].

 

Хотите знать больше?

Предыдущая информация была предназначена прежде всего для того, чтобы ознакомить вас с базовыми основами языка Objective-C. Охваченный в данном материале предмет отражает лишь некоторые особенности языка, с которыми вы наверняка встретитесь. Однако вам необходимо знать, что описанные здесь особенности — не единственные, поэтому мы всегда поощряем читать больше об Objective-C в документе The Objective-C 2.0 Programming Language.

 

Оригинал статьи (англ.) находится по адресу:http://developer.apple.com/iphone/gettingstarted/docs/objectivecprimer.action

 

Нарзикулов Фируз

http://www.insk.org

http://pyobjc.ru

 


 

1    http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/OOP_ObjC/index.html

2    http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/CocoaFundamentals/Introduction/chapter_1_section_1.html

3    http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/ObjectiveC/index.html

Изучаем Objective-C: Букварь
Метки:            

Изучаем Objective-C: Букварь: 2 комментария

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *