Objective-C: зачем оно, и с чем его есть

написал Владимир Пузанов - June 17, 2008 – 12:45

Не люблю я необоснованной критики. “Objective-C не труъ ибо под OSX и проприетарщина” и тому подобное. Давайте все же рассмотрим, что есть Objective-C и с чем его едят. При этом я буду оперировать языком на платформе Linux/i386, для того чтобы заведомо не привязыватся к проприетарным компонентам. В качестве компилятора используется gcc (GCC) 4.2.4 (Gentoo 4.2.4 p1.0). Это “ванильный” GCC с точки зрения патчей от Apple, к примеру GCC на моем ноутбуке идентифицирует себя как: i686-apple-darwin9-gcc-4.0.1 (GCC) 4.0.1 (Apple Inc. build 5483).

И так, простенький helloworld.m:

#include 

int main(int argc, char **argv)
{
	printf("Hello, world!\n");
}

Это вполне самостоятельное Obj-C приложение. Как вы заметили, это 100%-валидный C код. Objective-C сохраняет (в отличие от C++) полную совместимость с C расширяя его функционал только одним синтаксическим элементом.

Давайте добавим ООП, и посмотрим собственно на Objective-C.

#include 
#import 
#import 

@interface HelloWorld: Object
{
	char *greeting;
}

- initWithGreeting:(char*)text;
- (void)free;

- (void)sayHello;

@end

@implementation HelloWorld

- initWithGreeting:(char*)text
{
	if( (self = [super init]) ) {
		greeting = strdup(text);
	}
	return self;
}

- (void)free
{
	free(greeting);
	[super free];
}

- (void)sayHello
{
	printf("%s\n", greeting);
}

@end

int main(int argc, char **argv)
{
	HelloWorld *hw = [[HelloWorld alloc] initWithGreeting:"Hello, obj-c world!"];

	[hw sayHello];

	[hw free];
	return 0;
}

Два новых импорта (импорт технически эквивалентен #include, но не включает файл если он уже был включен; аналогичная функциональность есть в C/C++ компиляторе cl.exe из MSVC) расширяют код понятием Object. Данный класс является корневым, и входит в GCC.

Далее мы объявляем интерфейс класса и его реализацию. Паскалисты могут заметить некоторую сходесть с объявлением Unit’ов. Сам класс HelloWorld состоит из поля char *greeting (технически и по синтаксису блок является обычным struct) и нескольких методов. Знак “-” определяет метод экземпляра, “+” – метод класса. По умолчанию методы возвращают не int, а id (этакий void* для объектов).

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

Теперь перейдем к расширенному main(). В первой же строке вы видите достаточно длинную (и, может быть, неочевидную) конструкцию. На самом деле это просто вызов метода класса alloc, который возвращает id, для которого вызывается метод initWithGreeting. Результат записывается в переменную hw.

На самом деле запись [instance selector:attribute] подразумевает несколько более широкое понятие, чем вызов метода в Python или C++. Если копнуть глубже, то sayHello – функция C вида sayHello(id self, SEL _selector) (естественно с некоторым манглингом имени). Первые два агрумента похожи на питоновское определение метода с обязательным первым аргументом self, но, как и в C++, передаются неявно.

Для компиляции кода необходимо слинковатся с libobjc.so, в которой реализован класс Object и “системные” функции по вызову методов.

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

В следующий раз я рассмотрю возможности libFoundation. Либо Cocotron, если удастся “оторвать” его от XCode и собрать в линуксе.

  1. 5 Ответов к “Objective-C: зачем оно, и с чем его есть”

  2. напоминает С#

    зачем юзать квадратные скобки?

    написал rilian на Jun 17, 2008

  3. В смысле – почему именно квадратные, или что это значит синтаксически? ИМХО потому, что это динамический вызов. В C/C++ нет ничего технически похожего, потому и синтаксис непохожий. Да и первые трансляторы Obj-C -> C было проще писать.

    написал Владимир Пузанов на Jun 17, 2008

  4. Реалізація ООП негарна аж ніяк.

    написал post-factum на Jun 17, 2008

  5. И всё-таки, чем оно лучше С?

    написал Malor на Jun 17, 2008

  6. > Реалізація ООП негарна аж ніяк.

    Привыкаемо. Зато функционал ООП пошире чем в C++. Одни категории чего стоят!

    > И всё-таки, чем оно лучше С?

    Это ООП. Объектный подход. Я не говорю, что Obj-C лучше чем C – разные ниши. Я говорю о том, что это вполне самостоятельный язык, безо всяких привязок к Apple.

    написал Владимир Пузанов на Jun 17, 2008

Написать комментарий