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

Часть пятая, все ещё Objective...

(Продолжение. Начало в №30)

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


Немного лирики

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

Не секрет, что периодически разные эксперты составляют рейтинги наиболее популярных в мире языков программирования. Одним из самых известных среди подобных рейтингов является "топ", составляемый компанией TIOBE Software. Конечно, в этом рейтинге Objective-C по-прежнему занимает не самые высокие места, но в данном случае главное - тенденция. Для языка программирования, который раньше вообще не попадал в ТОП-20, позиция в самом начале второй десятки - очень неплохой результат, который говорит о том, насколько сильно "айфономания" подогрела интерес к Objective-C. Судя по тому, какой интерес испытывает публика к iPhone 4, дальше позиции Objective-C будут расти еще быстрее, а это означает, что специалисты, владеющие этим языком программирования, будут востребованы всё больше и больше. Так что изучение Objective-C - это вложение сил и времени в светлое завтра востребованного программиста.


И всё-таки, Objective-C...

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

#import "Rect.h"
@implementation Rect
+ newRect
{
 Rect * rect = [[Rect alloc] init];
 [rect setWidth: 1.0f];
 [rect setHeight: 1.0f];
 [rect setX: 0.0f y: 0.0f];
 return rect;
}
- (float) width
{
 return width;
}
- (float) height
{
 return height;
}
- (float) area
{
 return [self width] * [self height];
}
- (void) setWidth: (float) theWidth
{
 width = theWidth;
}
- (void) setHeight: (float) theHeight
{
 height = theHeight;
}
- (void) setX: (float) theX y: (float) theY
{
 x = theX;
 y = theY;
}
@end

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

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

Обратите также внимание на достаточно необычную для большинства компилируемых языков программирования ситуацию, когда можно не указывать тип возвращаемого методом значения, - по умолчанию считается, что оно имеет тип id, то есть является произвольным объектом. Нужно сказать также, что модель посылки сообщений объектам позволяет реализовывать методы, имеющие произвольное число параметров, - тоже не совсем обычно для компилируемых языков. Выглядит на практике такой метод примерно следующим образом (без кавычек, конечно): "- someMethod: (id) object, ...;".


Многопоточность и синхронизация

Может, конечно, вопрос создания многопоточных приложений действительно не такой уж и злободневный для тех, кто планирует писать приложения под iPhone, но, тем не менее, не рассказать о возможностях Objective-C в плане работы с несколькими потоками было бы, по меньшей мере, не вполне правильно. Так что мы с вами все-таки обсудим многопоточное программирование средствами Objective-C.

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

В общем-то, еще раз повторюсь, вряд ли вам на первых порах понадобится работать с потоками при написании программ под iPhone, но, в любом случае, думаю, будет совсем не лишним иметь в виду наличие такой возможности, потому что популярность "обычной" Mac OS X, при программировании под которую работа с несколькими потоками будет совсем не лишней, заставляет сегодня разработчиков реализовывать версии своих приложений, написанных изначально под Windows, для этой операционной системы. Так что знание Objective-C будет полезно еще и с этой точки зрения.


Ещё немного о работе с объектами

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

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


Источники для изучения Objective-C

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

Если вы предпочитаете изучать языки по русскоязычным книгам, то вам стоит обратиться к пособию "Objective-C 2.0 и программирование для Mac. Учебник и примеры", авторами которого являются Марк Далримпл и Скотт Кнастер. Конечно, сегодня компьютерная литература не относится к разряду очень дешевых, но это можно рассматривать как инвестиции в личный рост... Да и потом, если вы вдруг решите приобрести для разработки сам iPhone и компьютер производства Apple, то на фоне их стоимости цена книги уже вряд ли будет смотреться внушительно.

Если говорить о разработке именно под iPhone (а о ней мы сейчас и говорим), то здесь можно порекомендовать книги "iPhone SDK. Разработка приложений" и "iPhone. Разработка приложений с открытым кодом" Джонатана Здзиарски.

Что касается сетевых русскоязычных источников, то начать можно, например, с pyobjc.ru/2008/07/19/vvedenie-v-objective-c. А так, конечно, как говорится, Гугл в помощь. Это же касается и англоязычных ресурсов по Objective-C, которых в последнее время по вполне понятным причинам становится всё больше и больше. Ну и самое главное, конечно, помнить, что никакие книги и статьи не избавят вас от необходимости практиковаться в написании кода на Objective-C (желательно, конечно же, именно под iPhone).

(Продолжение следует)

Вадим СТАНКЕВИЧ,
dreamdrusch@tut.by

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

Номер: 

35 за 2010 год

Рубрика: 

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

Комментарии

Аватар пользователя Логик
Вадим СТАНКЕВИЧ привёл код:

- (void) setX: (float) theX y: (float) theY

{

x = theX;

y = theY;

}

Вопрос - как называется этот "метод"? setX: ? - Допустим, то есть, в переводе на Java, вызов типа:

rect.setX(X, Y)

Не странно ли, назвать метод setX:, а устанавливает и X и Y?

Откинем "методы", а для понимания будем использовать "посылка сообщений", тогда, - что описывает вышеприведенный код - он описывает ОБРАБОТЧИК сообщения, или ТЕЛО МЕТОДА ОБРАБОТЧИКА сообщения. - Как называется этот МЕТОД ОБРАБОТЧИКА сообщения? - ответ - НЕ ИМЕЕТ значения!

А что имеет значение - а то, КАКОЙ ТИП(вид) сообщения обрабатывает данный обработчик сообщения? - Ответ, данный обработчик сообщения обрабатывает сообщение типа: "setX: y:" и ТОЛЬКО ЕГО!

Нюансы:

Как послать это сообщение объекту типа Rect? - в коде у СТАНКЕВИЧа это приведено:

[rect setX: 0.0f y: 0.0f];

Как можно описать это через понятие "метод"? - Типа так, у объекта типа rect вызывается метод setX: с параметрами, первый параметр метода setX: безымянный(!!!) и равен 0.0f, второй параметр метода setX: имеет имя y: и равен 0.0f. - Круто?! Мозги НЕ поломали ещё? ;-)

А теперь опишем тоже, через понятие "посылка сообщений": Типа так, объекту типа rect посылается сообщение "setX: y:" имеющее два параметра, первый параметр иммет имя setX: и значение 0.0f, второй параметр имеет имя y: и значение 0.0f. - Отлично, - И мозги устаканились! ;-)

Вообще, сообщение "setX: y:" лучше бы назвать(для понимания) - "setX: setY:" и вызывать как:

[rect setX: 0.0f setY: 0.0f];

А еще лучше (для понятливости) - назвать: "X: Y:" и вызывать как:

[rect X: 0.0f Y: 0.0f];

А код обработчика этого сообщения определить как:

- (void) X: (float) X Y: (float) Y

{

x = X;

y = Y;

}

Почему так? - Дело в том, что если написать так:

- (void) setX: (float) X setY: (float) Y

{

x = X;

y = Y;

}

То setX и setY - это имена(!) параметров сообщения, а X и Y - это переменные куда помещаются значение(!) этих параметров, - в теле обработчика нельзя использовать имена параметров, а можно только имена переменных куда помещаются значение этих параметров. Для того, чтобы не "спотыкаться", часто пишут например так:

- (void) amount: (int) amount price: (int) price

{

summa = amount * price;

}

А посылают сообщение так( тут kassa - объект определённого типа, который может обрабатывать сообщения типа "amount: price:"):

[kassa amount: 2 price: 500];

А если же определить обработчик этого сообщения как:

- (void) amount: (int) valueAmount price: (int) valuePrice

{

summa = amount * price;

}

То посылать сообщение можно так же:

[kassa amount: 2 price: 500];

А вот компилятор(!) в этом случае выдаст ошибку, ибо нет таких переменных для него как amount и price, а есть переменные valueAmount и valuePrice и код обработчика пришлось бы исправить на:

- (void) amount: (int) valueAmount price: (int) valuePrice

{

summa = valueAmount * valuePrice;

}

Чтобы с этим НЕ заморачиваться, многие предпочитают наименование(!) параметров и наименование переменных(!) куда помещаются значения этих параметров называть одним именем.

Таким образом, мысленный переход от "вызываем метод у объекта" к "посылаем сообщение объекту" приводит мозги программиста в порядок. имхо :-)

Аватар пользователя Инкогнито
Статья - нулевая!

И нехрен удалять отзывы читателей!!!

Аватар пользователя Инкогнито
Модератор, перестаньте удалять правду о Станкевиче! Может хоть так до него дойдет, что ему пора уйти из газеты!