Как написать программу для iPhone
Мы с вами уже достаточно подробно обсудили, какими именно языками программирования можно пользоваться при создании приложений под операционную систему iOS (то есть, фактически, для коммуникатора iPhone). Сегодня подробно остановимся на самом главном из языков программирования для этой платформы - то есть, конечно же, на Objective-C.
Немного истории
Сегодня Objective C используется, в основном, компанией Apple (ну и, соответственно, теми, кто пишет приложения под её платформы Mac OS X и iOS). Но появился язык Objective-C задолго до того, как "яблочники" продали свой первый iPhone - случилось это ещё в начале 80-х годов в компании Stepstone. Брэд Кокс, основатель этой компании, всерьез столкнулся с проблемой повторного использования однажды написанного программного кода. Возможности основного языка программирования, C, который использовался и в Stepstone, его не устраивали. Ему очень нравился Smalltalk, возможности которого в этом плане были как раз весьма хороши, но, будучи реалистом, он понимал, что если компания перейдет исключительно на Smalltalk, то её существование на рынке закончится достаточно скоро. В итоге было принято решение создать такой язык программирования, который смог бы объединить в себе и возможности Smalltalk, и синтаксис C. Так появился компилятор OOPC (от Object-Oriented Programming in C).
К 1986 году Кокс вместе со своим помощником Томом Лавом настолько увлеклись новым языком программирования, что всё своё время стали посвящать ему. В том же году они создали новую компанию Productivity Products International (PPI), призванную коммерциализировать их разработку. Для того, чтобы продвижение нового языка шло бодрее, ему придумали более "человеческое" название - Obj-C, которое было практически сразу расширено до Objective-C. Сложно сказать, как в дальнейшем сложилась бы судьба этого языка, если бы в 1988 году Стив Джобс, ушедший из Apple, не основал компанию NeXT, не обратил своё внимание на перспективное средство создания приложений.
В 1988 компания NeXT лицензировала Objective-C у PPI и выпустила свой собственный компилятор для этого языка, а также набор библиотек для разработки приложений под рабочие станции производства, понятное дело, всё той же компании NeXT. Поскольку компиляторы у компании продавались куда лучше рабочих станций, то в сравнительно скором времени новая фирма Джобса вовсе забросила "железный" бизнес и начала заниматься софтом - в том числе и получившим весьма широкое распространение NeXTstep'ом. Постепенно популярность языка увеличивалась, и в 1992-м свой проект по созданию компилятора Objective-C стартовал у GNU.
После того, как NeXT была куплена Apple (а произошло это в 1996 году), "яблочная" компания стала использовать её наработки в собственных продуктах. Так, в общем-то, и повелось с тех пор, что под "Маки" программируют на Objective-C. Конечно, это вызывает некоторое недовольствие у тех, кто приходит с других платформ и вынужден, таким образом, учить новый язык программирования, но Objective-C является важной частью общей стратегии Apple, так что вряд ли компания в обозримом будущем откажется от него в пользу чего-либо другого. Да и при ближайшем рассмотрении оказывается, что Objective-C вовсе не так уж плох, как можно было бы думать, зная, что этот язык достаточно стар и не слишком широко распространён. Впрочем, обо всём по порядку.
Объектный Си?
Собственно, суть этого языка заключена в самом его названии - это действительно, как можно было бы подумать, объектно-ориентированная надстройка над языком C. Надстройка, потому что компилятор Objective-C (правильный компилятор Objective-C) должен успешно справляться с программами на "чистом" C, то есть нормально их компилировать и выдавать на-гора результат своей работы. Но при этом тех, кто думает, что Objective-C - это какое-то новое название хорошо им знакомого C++, ожидает жестокое разочарование, потому что, несмотря на то, что эти два языка имеют общего предка и исповедуют объектно-ориентированный подход, общего у них вовсе не так много, как могло бы показаться на первый взгляд.
Дело всё в том, что Objective-C реализует подход к объектно-ориентированному программированию, который изначально был придуман в Smalltalk'е. В результате, например, очень многие вещи здесь выглядят странно для того, кто привык к тому же C++ - например, динамичность компилируемого языка, когда многие решения в программе принимаются не компилятором, а ею самой уже во время выполнения.
Самая Smalltalk'овская особенность Objective-C, которая поначалу наверняка будет восприниматься не слишком хорошо теми, кто привык к C++ и другим похожим по объектной модели языкам программирования, заключается в том, что в этом языке нет привычного вызова методов. Вместо этого здесь используется несколько иная концепция, заключающаяся в отправке объектам сообщений. Как написано в книжках по Objective-C, этот язык является message-oriented, в то время как о С++ можно сказать, что он function-oriented. Как утверждают сторонники Smalltalk'овского подхода к объектам, он имеет такое количество преимуществ, что просто, как говорится, ни в сказке сказать, ни пером описать.
Главный из этих плюсов заключается в том, что любому объекту можно послать любое сообщение, и это не вызовет у объекта "аллергической реакции". Если объект не может обработать это сообщение, он пересылает его другому объекту, который уже будет заниматься обработкой (это называется делегированием). Именно на этапе выполнения программы происходит привязка пришедшего сообщения к вызову той или иной функции, что и составляет ту самую "динамичность" языка, о которой я говорил выше. Модель с использованием сообщений удобна также и при написании распределенных приложений - объекты, находящиеся в разных адресных пространствах, легко могут обмениваться сообщениями друг с другом.
Как и многие языки, выполняющиеся на виртуальных машинах (ну хорошо, в специальных средах исполнения - согласен, так будет более правильно и точно), Objective-C поддерживает получение метаинформации об объектах. То есть, говоря русским языком, вы в любой момент можете спросить у объекта (именно на этапе выполнения программы), какой у него класс, какие он поддерживает методы, проверить, является ли класс потомком того или иного класса, и так далее. Конечно, нельзя сказать, чтобы это было так уж прямо диковинно для компилируемых языков программирования - можно вспомнить тот же Delphi, в котором объектная модель тоже позволяет получать такую информацию, но в Objective-C это всё было гораздо раньше.
Одним из плюсов языка я также считаю отсутствие поддержки множественного наследования (вместе с отсутствием вытекающих из него последствий) - ведь не зря же все более современные языки программирования не поддерживают реализованного в C++ множественного наследования. Но это, конечно, только ещё один повод для адептов этого языка кинуть камень в огород Objective-C. Впрочем, о вкусах не спорят...
Немного о синтаксисе
Конечно, и синтаксис Objective-C отличается от синтаксиса того же C++ и взросших благодаря ему языков программирования. Например, привычная конструкция вызова объекта, которая в C++ записывалась бы с использованием оператора "->", в Objective-C выглядит следующим образом: [obj method: argument];. В общем-то, различие здесь даже не в стиле C++ и Objective-C, а в том, какой синтаксис имели их объектно-ориентированные предки - Simula и Smalltalk. И здесь, опять-таки, уместно вспомнить обсуждавшуюся выше концепцию отсылки сообщений объектам, благодаря которой и приобретает смысл такой несколько странный, на первый взгляд, синтаксис. В случае со стилем записи Simula/C++ вы не можете организовать отсылку одного и того же сообщения с одними и теми же аргументами целой коллекции объектов (да-да, можно, конечно, извернуться, чтобы достичь приблизительно того же эффекта, но так просто и изящно записать эту конструкцию у вас не получится). При этом совсем не обязательно, что все те объекты, которым вы рассылаете сообщение, будут его как-то обрабатывать (см. выше - его, например, можно делегировать или просто пропустить).
Для работы с объектами в Objective-C есть специальный тип id. Фактически, такой тип имеет любой объект, и можно даже сказать, что этот тип является указателем на объект. Из этого можно сделать вывод, что язык не поддерживает проверки типов, но это не совсем верно. Можно использовать (и на практике в большинстве случаев именно так и поступают) обозначение с явным указанием класса - оно позволит осуществить компилятору и некоторую проверку типов, то есть узнать, поддерживается ли конкретное сообщение конкретным объектом. Если не поддерживается, то ничего страшного не произойдет - вам выдадут не ошибку, а всего лишь предупреждение.
В общем и целом, как видите, ничего особенно страшного Objective-C в себе не несет, хотя, конечно, для тех, кто всегда писал на C++, Java, C# и прочих популярных объектно-ориентированных языках, привыкнуть к доставшемуся "в наследство" от Smalltalk'а синтаксису будет не просто. Но, как правильно пишут в книгах по этому языку, его изучение вряд ли вызовет серьезные трудности.
Конечно, в одной статье обсудить все особенности Objective-C практически невозможно, поэтому продолжим разговор в следующий раз.
Вадим СТАНКЕВИЧ,
dreamdrusch@tut.by