Objective-C

Всё программирование для iPhone и Cocoa MacOS X ведётся с помощью языка Objective-C.
Objective-C создан в давних 80-ых Брэдом Коксом и Томом Лав. Objective-C является надстройкой надо языком С и даёт возможность писать обычный С-код. Objective-C привносит объектно-ориентированные возможности, которые заимствует у Smalltalk. Первоначально концепции и терминология Objective-C вызывает некоторое замешательство. Но тут дело привычки и после недолгой работы, странный синтаксис уже не выглядит так непривычно.


Итак, Objective-C — это объектно-ориентированный язык, что значит полную поддержку объектов, членов-данных, методов, инкапсуляции, наследования и полиморфизма и всего что с этим связано. Заголовочный файл (.h) и файл реализации (.m) — вместе представляют собой объект в терминах Objective-C. В какой-то момент времени вы будете использовать встроенные объекты, которые поставляются с framework iPhone OS, но гораздо чаще вам придётся разрабатывать новые классы или наследоваться от уже существующих, чтобы добавить новое поведение. Когда будете это делать, вам необходимо будет добавить новую пару файлов (.h) и (.m), которые будут представлять ваш новый класс.

Рассмотрим шесть основных синтаксических элементов языка Objective-C:

  • Category — категория применяется для того, чтобы расширить класс без использования механизма наследования;
  • Class — класс он и есть класс, определяет тип объекта;
  • Message — сообщение, это команда, которая посылается объекту. Другими словами — вызов метода;
  • Properties — свойства дают возможность удобного использования методов Get/Set;
  • Protocols — протокол определяет методы, которые обязательны для реализации, по аналогии с interface в C#;
  • @ — директива, используется компилятором.

Теперь по порядку.

Message — сообщение

Сообщение посылается, когда один объект просит дугой выполнить определённое действие. Говоря привычным нам языком — послать сообщение, значит выполнить вызов функции/метода. Вызов простого сообщения выглядит следующим образом:

Более жизненные пример:

Здесь сообщение посылает объекту window команду makeKeyAndVisible, которая говорит ему отобразиться и начать принимать ввод от пользователя.

Если бы я делал то же самое на C#, то приведённая конструкция была бы записана window.makeKeyAndVisible(); На первых порах это мне это было воспринимать легче, позже привык к записи Objective-C.

Есть еще три способа использования сообщения:

  1. сообщение может принимать аргументы;
  2. сообщения можно каскадировать;
  3. сообщение может быть передано одному из нескольких получателей.

Сообщение с аргументами

Чтобы отправить сообщение с одним аргументом, достаточно разделить двоеточием именем сообщения и аргументом. Пример:

Пример из жизни:

В C# я бы написал вот так: textView.setText(@«Hello world!»);

Если необходимо отправить сообщение с несколькими аргументами, тогда каждый аргумент, кроме первого снабжается меткой. Пример:

Пример из жизни:

В C# я бы написал вот так myButton.setTitle(@«OK», UIControlStateNormal);

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

Каскадные сообщения

Тут думаю всё понятно. Сообщения мы можем каскадировать вкладывая одно в другое, пример:

Другими словами это выражение можно было бы записать:

Получатели сообщения

Сообщение можно отправить классу:

Пример:

В примере классу UIButton отправляется сообщение buttonWithType с аргументом UIButtonTypeRoundedRect. То же самое в C# я бы написал так: UIButton myButton = UIButton.buttonWithType(UIButtonTypeRoundedRect);

Получается, что метод buttonWithType класса UIButton является статическим.

Сообщение можно отправить объекту (экземпляру) класса, пример я уже приводил выше

здесь сообщение initWithFrame с аргументом textFieldFrame отправляется объекту (экземпляру) класса UITextView.

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

Думаю тут всё понятно. В C# я бы написал вот так: this.setText(@«Hello World!»);

Отправляем сообщение предку. В C# я бы записал это так: base.initWithFrame(frame);

Определение класса

Интерфейс

Классы в Objective-C определяются в паре файлов (.h), (.m). В файле (.h) определяется интерфейс класса, а в файле (.m) реализация этого класса. Определение интрерфейса класса начинается с директивы @interface и заканчивается директивой @end. Сразу же пример:

Здесь мы определили класс MyClass, который является наследником класса UIImageView. Класс имеет переменную strTitle и экземплярный метод showTitle.

На C# я бы то же самое записал так:

Здесь интересный тонкий момент, который, возможно, вам уже бросился в глаза — это странный знак «-» перед определением метода. Так в Objective-C определяется экземплярный метод, который можно использовать только после создания объекта данного класса. Знак «+» означает, что мы определяем метод класса или статический метод. Для обеспечения динамической типизации или определения типа во время выполнения применяется ключевое слово id, которое является указателем на «любой объект».

Реализация

Реализация осуществляется в (.m) файле и начинается с директивы @implementation и завершается директивой @end. Пример:

Пример начинается с директивы #import, которая является аналогом директивы #include. Так же #import имеет дополнительную функциональность, которая гарантирует, что заголовочный файл будет включен всего один раз. Что является аналогом такого кода на C/C++:

Не знаю, нужны ли тут какие-либо комментарии ещё к реализации. По-моему понятно.

Свойства

Необходимость свойств в том, чтобы избавиться от написания огромного количества методов getter-ов/setter-ов. Язык Objective-C предлагает синтаксис для упрощения доступа к экземплярным переменным. Директива @property является частью выражения @interface и предназначена для организации доступа к экземплярной переменной. Сразу к примеру:

Определения свойства начинается с определения экземплярной переменной, далее используя директиву @property мы повторяем это определение. И завершаем директивой @synthesize в файле реализации класса @implementation. Вот в общем-то и всё, мы определили метод доступа к экземплярной переменной, который может читать и писать в переменную. По-умолчанию свойство имеет тип assign, но мы можем изменить это, указав соответствующий атрибут. Пример использования свойства:

Синтаксис «.»

Objective-C предлагает синтаксис «.», чтобы упростить использование свойств объекта. Ниже пример, который я привёл выше, но уже с использованием синтаксиса «.»:

По-моему так проще, по крайней мере, мне как человеку из мира C++/C# — эта запись привычна и узнаваема. Так же синтаксис «.» может быть каскадирован, т.е. выражение myClass.Array.Length законно и применимо.

Это не всё по свойствам. Свойства так же могут включать атрибуты, которые меняют поведение свойства при присваивании и метод доступа к свойству. Свойства могут быть динамическими, т.е. добавляться во время выполнения, с помощью директивы @dynamic. И многое другое, но здесь и сейчас я не буду это рассматривать.

Категории и протоколы

Два последних элемента Objective-C, которых я бы хотел коснуться — категория и протокол.

Категоря

Про категорию общими словами.

Категория пришла в Objective-C из мира Smalltalk. Категория используется в случае, если вы хотите добавить поведение к классу без наследования от него. Т.е. категория позволяет расширить класс и добавить новые методы к нему и при этом не требуется исходных текстов класса, так же добавленные методы автоматически становятся доступными всем классам, унаследованным от изменяемого. Механизм, позволяющий расширять уже существующие классы (путем добавления новых методов, новые экземплярные переменные добавить таким образом нельзя), называется категориями. Как обычно, вы начинаете с создания пары файлов содержащих интерфейс @interface и реализацию @implementation.

Категория имеет свое имя, список методов и имя класса, который она расширяет. Описание категории имеет следующий вид:

Реализация категории выглядит следующим образом:

Больше в категории углубляться не буду.

Протокол

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

Описание протокола:

Пример более жизненный:

Протокол может наследовать от произвольного количества других протоколов

Возможно при описании класса задать не только родительский класс, но и набор протоколов:

 


Похожие записи:

Оставить комментарий

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