Objective-C: Rubyist's insight

19 Aug 2011

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 do
object.method args
# what ruby actually does
object.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.

If you use clang3, it can make it throw errors when compiling.

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:

class String
  def hello_world
    "Hey"
  end
end

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:

@interface NSString (HelloWorld)
+ (NSString *)helloWorld;
@end

@implementation NSString (HelloWorld)
+ (NSString *)helloWorld
{
  return @"Hey";
}
@end

Usually categories are saved in files named like ClassToBeExtended+CategoryName – e.g. NSString+HelloWorld.h and NSString+HelloWorld.m, and then are imported.

Here are several things that simplified my understanding of Objective-C. Hope this article is helpful for you. Good luck!