Как написать программу для iPhone

Часть четвёртая, ещё более объектно-ориентированная

Мы с вами уже обсудили некоторые аспекты программирования на Objective-C - основном языке создания приложения для платформы Apple iOS, используемой в коммуникаторе iPhone, плеере iPod и планшете iPad. Сегодня продолжим знакомство с этим языком.

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


Протоколы

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

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

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

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


Рождение и смерть объектов

Казалось бы, чем может один объектно-ориентированный язык программирования отличаться от другого языка, основанного также на объектной парадигме, в области создания и уничтожения объектов? Но после того, как привычные вызовы методов заменились отсылкой сообщений объектам, логично было бы предположить, что и во многих других отношениях Objective-C отличается от правящих сегодня бал Java, C++, C# и т.д. Что ж, такое предположение действительно оправдывается...

В Objective-C для создания объекта необходимо выделить под него память, а затем инициализировать этот самый объект. Первая часть этой процедуры выполняется с помощью метода alloc, который есть в базовом классе Apple'овской runtime-библиотеки для Objective-C. Сама инициализация значения полей осуществляется методами, которые нужно писать, что называется, "ручками". Традиционно таким методам дают имена, начинающиеся с "init", но, в общем-то, сами понимаете, что это, скорее, для удобства, чем из каких-то других соображений. Выглядит же это всё в итоге следующим образом:

id anObject = [[Rectangle alloc] init];

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

В общем-то, конечно, в таком разнесении одного конструктора на два разных метода наверняка можно найти свои плюсы, хотя и не очень очевидные и явно не слишком часто нужные большинству программистов. В случае, если вы хотите использовать привычные конструкторы, а не alloc'и и init'ы, вы вполне можете быстро написать метод, объединяющий их, и пользоваться им практически как привычным конструктором. Но, с другой стороны, конечно, для стандартных классов, которые вы обязательно будете использовать в программировании под iPhone, таких методов не будет...

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

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

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

Что ж, пожалуй, не буду перегружать вас рассказами об Objective-C и его возможностях и на сегодня закончу. Думаю, в следующий раз мы с вами еще немного поговорим о некоторых особенностях основного "яблочного" языка программирования, но сильно этот разговор постараемся не затягивать, потому что всё-таки нас интересует не столько сам язык, сколько создание приложений для платформы iOS.

Вадим СТАНКЕВИЧ

Версия для печатиВерсия для печати

Номер: 

34 за 2010 год

Рубрика: 

Software
Заметили ошибку? Выделите ее мышкой и нажмите Ctrl+Enter!

Комментарии

Страницы

Аватар пользователя Инкогнито
Пятая статья про программирование для айфона, а ещё даже до хеллоуворда не добрались. Отэтода!

Люди в андроидах уже скрипты с вибрацией фигячат.

Аватар пользователя Инкогнито
Диагноз: В.Станкевич.

Лечение: не представляется возможным.

Аватар пользователя Логик
>Люди в андроидах уже скрипты с вибрацией фигячат.

Но это всё равно не помогает им обогнать айфон. Ибо от фигяченья одно фигяченье и выходит, похоже. имхо

Аватар пользователя Логик
Вадим СТАНКЕВИЧ, я думаю, можно частично наплевать на wiki и прочее и громко заявить:

- в Objective-C МЕТОДОВ НЕТ!!!

А что есть? - в Objective-C МЕТОДОВ НЕТ, а есть СООБЩЕНИЯ!

Иначе нам не связать логически сл. предложения:

"Но после того, как привычные вызовы методов(!) заменились отсылкой сообщений(!) объектам, логично было бы предположить, что и во многих других отношениях Objective-C отличается от правящих сегодня бал Java, C++, C# и т.д."

Но далее: "В Objective-C для создания объекта необходимо выделить под него память, а затем инициализировать этот самый объект. Первая часть этой процедуры выполняется с помощью метода(?) alloc, который есть в базовом классе Apple'овской runtime-библиотеки для Objective-C. Сама инициализация значения полей осуществляется методами(?), которые нужно писать, что называется, "ручками"."

Если МЕТОДОВ нет, а есть посылка сообщений, то эти вышеприведенные предложения противоречат друг другу. имхо

Одно из ввух - либо методы есть, либо их нет, а есть сообщения.

Кстати, а что будет если объекту послать сообщение, которое в нём(в описании класса этого объекта) вообще(!) не определено? - Ответ "объекту дается последний шанс обработать сообщение(!!!) перед вызовом исключения — ... объекту посылается сообщение forwardInvocation: ... Если объект поддерживает forwardInvocation:, то он может либо сам обработать посылаемое сообщение, либо переслать другому объекту для обработки..."

Таким образом, объект в Objective-C может принимать ЛЮБЫЕ(!!!) посылаемые ему СООБЩЕНИЯ, даже не имея никаких реализаций КОНКРЕТНЫХ сообщений.

Я думаю, что смешение слов "метод" и "посылка сообщений" делается с целью облегчения усвоения перехода(изучения) программистов Java, С++ и прочих, но, по моему, это более приводит к путанице и непониманию, ибо перевести на "язык методов", предложение типа:

"объект в Objective-C может принимать ЛЮБЫЕ(!!!) посылаемые ему СООБЩЕНИЯ"

если и можно, то коряво:

"у объекта Objective-C можно вызвать ЛЮБОЙ(???) метод(?), даже не описанный в описании класса, в этом случае будет вызван метод forwardInvocation: , если он описан в классе объекта." - эта фраза, в отличии от предыдущей, может вызвать ступор у начинающего изучать Objective-C.

имхо

В Objective-C МЕТОДОВ НЕТ, а есть СООБЩЕНИЯ!

Аватар пользователя Логик
Более точно:

В Objective-C ВЫЗОВОВ МЕТОДОВ НЕТ, а есть ПЕРЕДАЧА СООБЩЕНИЙ!

Под словами "метод" следует понимать "обработчик сообщения" (сообщенИЙ - для forwardInvocation:).

Аватар пользователя Инкогнито
>Но это всё равно не помогает им обогнать айфон.

Уже обогнал

http://www.sotovik.ru/news/android-obognal-iphone.html

Аватар пользователя Логик
>Уже обогнал

http://www.sotovik.ru/news/android-obognal-iphone.html

"На мировой мобильной арене охват Android-телефонов сейчас шире в сравнении с iPhone-экосистемой, заявили аналитики Gartner. В Северной Америке мобильная Google-платформа лидирует, а глобально занимает третью позицию среди операционных систем для смартфонов."

Но, в общем то, нас интересуют ПРОДАЖИ софта для iPhone и для Android. - Как обстоит с ними? - Кто КРУЧЕ?

Аватар пользователя Инкогнито
>Но, в общем то, нас интересуют ПРОДАЖИ софта для iPhone

Платный софт - это в основном игры. Игр под айфон больше. И что с того?

Преимущества айфона только игрушки. А скоро выйдет ВинФоне 7, так она быстро обскачет айфон по играм.

Аватар пользователя Логик
>Платный софт - это в основном игры. Игр под айфон больше. И что с того?

Платный софт НЕ только и НЕ сколько игрушки - это фактически ЛЮБОЙ софт для айфона. Почти каждая бесплатная прога для айфона есть в большинстве типа Litе - то есть наживка для покупки Pro версии.

>А скоро выйдет ВинФоне 7, так она быстро обскачет айфон по играм.

Типа пошутил? ;-)

Аватар пользователя Логик
"В прошлую субботу зарубежный ресурс 148Apps насчитал 252,227 приложений, доступных для iPad и iPhone/iPod Touch. Большая часть из них не отличается либо качеством, либо функциональностью, а чаще всего — и тем, и другим одновременно. Однако среди такого огромного количества софта есть и настоящие шедевры, аналогов которым нет на других платформах. Кстати, об этих самых других платформах. По неофициальной статистике, в Android Store сегодня около 100 тысяч приложений, а в App World (Blackberry) — всего 9 тысяч. Разница, заметная невооруженным глазом."

Страницы