Intro

Before I started learning Objective-C, I did some PHP, then Python and
Ruby. I like Ruby most of all. I like it for its simplicity, pithiness,
and at the same time, for its power. About a week later (this post was
originally written in Russian on 26th Jul –
link) I got hackintosh on
my PC up and running (now I own a MacBook Early 2008 Black). It was OS X
Lion GM. I knew that the applications for Macs and iPhones are written
in Objective-C, I even tried to learn Objective-C, but without a Mac
that kind of learning was unpleasant. I installed Xcode 4.2, I have
written several simple console apps. And each time I followed some
tutorial, or just tried to do stuff myself, I kept noticing similarities
between Ruby and Objective-C (and it’s very logical – both languages
are influenced by Smalltalk),
although they serve different purpose.

So I’ll describe a few things that will help Rubyists to understand
Objective-C. These things are mostly theoretical, without the snippets
of code. I apologize if some thing are not explained The C Way, I came
from The World of Ruby. And sorry for my not good enough English.

1. Dynamicity

We all know that Ruby is a dynamic programming language. Okay but what’s
with Objective-C? Isn’t it just a superset of C? Not quite. Objective-C
makes many decisions (e.g. sending a message, etc) at runtime and not at compile time.

2. Object model

Everything is an object in Ruby. This isn’t always true for Objective-C.
As Objective-C is superset of C, basic data types (like char, float,
double, int, struct) aren’t objects. However Foundation.framework
provides the functional wrappers around them as well as such ordinary
things for Rubyists like Strings, Mutable Arrays, Hashes, etc.

3. Sending messages

In Ruby, when we call an object method we actually send a message to the
object:

# what you doobject.methodargs# what ruby actually doesobject.send:method,args

That is, the method call is converted to passing a message. The same
thing happens with Objective-C:

# what you do
[object method];
# what actually happens
objc_msgSend(object, @selector(method));

This is precisely passing of a message and not a method call, because if
we call a non-existent method we don’t get any errors at compile time,
only at runtime (that proves that Objective-C is dynamic too). At
compile time [object method] is converted to C-call of
objc_sendMsg(id object, SEL selector) function.

BTW, in the terminology of C++, methods in both Ruby and Objective-C are virtual.

4. Non-strict typing

Each developer in Ruby knows that they don’t have to care about types.
But not everyone knows that with Objective-C they can forget about types
as well. If the type of the object is unknown to us yet, we can just
specify the type of object as id, that means that variable can hold
value of any type. id is kinda like a pointer to any object.

Okay it’s all good. But what with C-types? No, it doesn’t work with
C-typesi. However we can use Foundation’s wrappers over C types like
NSNumber, NSString, NSArray, and so forth.

5. Class declaration, instances of objects, and properties

In Ruby we just define a class, in Objective-C we have to write both
interface and implementation for the class. In Ruby we can define any i-var from any method, in Objective-C we have to declare all i-vars we are going to use in an interface file.
An objects are created easily in both langs though. In Ruby we just send
new message to the class:

myObject=MyClass.new

In Objective-C we need to allocate memory for the object (alloc) and
then to initialize it (with init or initWith... method):

MyClass * myObject = [[MyClass alloc] init];

If we want to access the i-vars from the outside, we define getter and
setter methods. In Ruby we just write attr_accessor :var inside class
definition, in Objective-C we write type * variableName inside i-vars
definition block, @property(retain)type*variableName after methods
definition, and @synthesize variableName inside class implementation
file.

As Objective-C is a superset of C, we ought to care about memory. LLVM compiler however provides us with one interesting feature – Automatic Reference Counting, which takes care about freeing memory. Xcode 4.2 and newer uses LLVM compiler by default, so we can not care about memory. But for deeper Objective-C understanding I highly recommend you to spend some time understanding memory management.

6. Protocols and mixins

In Ruby we can define modules and then mix ‘em into the classes, in a
such way something like multiple inheritance is realized. In Objective-C
we haven’t modules. But we have protocols.

An informal protocol is a list of methods that a class can opt to implement. It is specified in the documentation, since it has no presence in the language. Informal protocols often include optional methods, which, if implemented, can change the behavior of a class. For example, a text field class might have a delegate that implements an informal protocol with an optional method for performing auto-completion of user-typed text. The text field discovers whether the delegate implements that method (via reflection) and, if so, calls the delegate’s method to support the auto-complete feature.

And for example we can implement a method that can take any object that realizes Serializable protocol and be sure that the object can respond to serialize message.

7. Categories and class extension

If we want to extend a Ruby class, we can simply write:

classStringdefhello_world"Hey"endend

That way we added hello_world method to String class (but we can do
so in many ways). In Objective-C we can do something similar using
categories: