Pull to refresh

Objective-C: взгляд рубиста

Reading time 4 min
Views 5.7K

Intro


До начала изучения Objective-C я программировал сначала на PHP, потом на Python и Ruby. Ruby мне понравился больше всего. Понравился своей простотой, лаконичностью, но в тоже время и мощностью. А около недели назад у меня наконец-таки получилось завести хакинтош на своем компьютере (сейчас у меня Macbook Early 2008 Black). Это оказался OS X Lion Golden Master. Я знал, что приложения для маков и айфонов пишут на Objective-C, даже пытался его выучить, но без OS X это было неприятно, что ли. Поставив Xcode 4.2 (я уже зарегистрированный iOS разработчик), написал несколько очень простых консольных приложений. И каждый раз когда я следовал какому-то туториалу, или просто пытался сам писать код, мне приходило в голову то, что, оказывается, Ruby и Objective-C имеют много общего (хотя это логично, так как оба языка были сделаны под влиянием Smalltalk), несмотря на то, что у этих двух языков совсем разные предназначения.
Итак, здесь я опишу некоторые вещи, которые помогут программистам на Ruby понять Objective-C, по большей части теоретические, без кода. Так же прошу прощения, если некоторые вещи будут объяснены не совсем по-сишному, я же пришел из мира Ruby.

1. Динамичность


Все мы знаем что Ruby — динамический язык программирования. Но как же Objective-C? Это же просто надстройка над C? Не совсем. Оказывается, Objective-C тоже в какой-то степени динамический язык. В нем многие вещи (например, отправка сообщения) и решения принимаются непосредственно во время запуска, а не во время компиляции.

2. Объектная модель


В Ruby, все — объект. Для Objective-C же это не всегда верно. Так как он является надстройкой над C, базовые типы данных (такие как char, float, double, int, struct) не являются объектами. Однако, фреймворк Foundation представляет функциональные обертки над ними, а так же такие, казалось бы, привычные вещи как строки, мутируемые массивы, хэши, и т.д.

3. Отправка сообщений


В Ruby когда мы вызываем метод объекта происходит неявная отправка сообщения:
object.send :method, args

то есть вызов метода преобразуется в отправку сообщения. В Objective-C происходит что-то похожее:
[object method];

Это именно посылка сообщения, а не вызов метода, поскольку если вызвать несуществующий метод, мы не получим никаких ошибок на этапе компиляции, только во время выполнения (что доказывает динамичность языка). Во время компиляции [object method] преобразуется в вызов C-шной функции objc_sendMsg(id object, SEL selector).

Как подсказывает farcaller в комментах:
clang3 на несуществующие методы умеет давать ошибки компиляции

Кстати, в терминологии языка C++ методы в Ruby и Objective-C являются виртуальными.

4. Нестрогая типизация


Каждый рубист знает, что с Ruby ему нет нужды заботится о типах переменных. Но не каждый знает, что в принципе c Objective-C — тоже. Если мы не знает тип объекта, в Objective-C можно просто указать тип объекта id, что значит — переменная может принимать значение любого типа. Ведь фактически, id — указатель на произвольный объект.
Однако для C-шных типов это не работает, только для объектов Objective-C. Хотя прибегать к типам C может потребоваться нечасто, ведь многие типы C имеют реализацию на Objective-C — NSNumber, NSString, NSArray, etc.

5. Объявления классов, создание объектов и свойства


В Ruby мы может просто определить в класс, в Objective-C мы вынуждены определить описание и саму реализацию класса. Обычно описание и реализация располагаются в разных файлах. В Ruby мы можем из любого метода определить любую переменную объекта, в Objective-C мы должны заранее определить все используемые внутри класса переменные.
В принципе, объекты создаются достаточно легко в обоих языках. В Ruby можно просто послать классу сообщение new
myObject = MyClass.new

в Objective-C же сначала необходимо выделить объекту память (alloc), а затем инициализировать его (init, initWith…)
MyClass * myObject = [[MyClass alloc] init];

Что бы получать доступ к instance-переменным мы должны определить два метода — геттер и сеттер. В Ruby мы можем просто написать attr_accessor :var, в Objective-C нам предстоит написать type * variable в разделе описания переменных класса, @property(retain) type * variable; после описания методов, и @synthesize variable; в реализации класса.

Небольшое отступление: поскольку Objective-C — надстройка над C, мы вынуждены заботится также и памяти. Компилятор LLVM поддерживает одну интересную фичу — Automatic Reference Counting, которая берет заботы об освобождении памяти на себя. Xcode версии 4.2 и выше использует компилятор от LLVM по-умолчанию, то есть о управлении памятью можно и не заботится, хотя, в принципе, для полного понимания языка было бы не плохо понять и такую, не совсем простую, тему как управление памятью.

6. Протоколы и миксины


В Ruby мы можем определять модули, а затем подмешивать их в классы, таким образом реализуется что-то вроде множественного наследования. В Objective-C конкретно такого нет. Зато в нем есть протоколы. Как говорит Wikipedia:

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

То есть, например, метод может принимать объекты, реализующий протокол Serializable и быть уверенным в том, что объект отвечает на сообщение serialize.

7. Категории и расширение классов


Если мы хотим расширить класс, в Ruby мы можем просто написать:

class String
  def my_super_method
    “New string”
  end
end


Таким образом мы добавим в класс метод my_super_method (хотя это и не единственный путь). В Objective-C мы можем сделать что-то похожее используя категории:

@interface NSString (HelloWorld)
+ (NSString *)helloWorld;
@end
@implementation NSString (HelloWorld)
+ (NSString *)helloWorld
{
  return @”Hello, World!”;
}
@end


Категории обычно сохраняются в файлы РасширяемыйКласс+НазваниеКатегории — NSString+HelloWorld.m и NSString+HelloWorld.h, а потом импортируются.

Вот лишь некоторые вещи, которые облегчили мне понимание Objective-C. Надеюсь, вам было интересно. Удачи!

Рекомендую обратить внимание на:


Tags:
Hubs:
+43
Comments 103
Comments Comments 103

Articles