An Introduction to Objective-C for .NET Developers

Over the past year or so I have gone from primarily developing applications using .NET/C# and ASP.NET MVC, to writing iOS applications using Objective-C/Cocoa and using Ruby/Rails for web development.

It’s been an amazing experience, but it can take some time to get used to a new language and platform.

I have found the more languages I learn, the easier it gets to pick up new ones. Many of the core concepts are the same, it’s just a matter of learning the peculiarities of each language/platform (unless you’re learning learning a whole new paradigm, like a functional language).

One thing I find useful when learning a new language is to try and relate certain features back to a language I know and understand. Of course, it’s important to learn the correct conventions for a new language, but that usually happens over time.

For the purpose of this post, I’m going to create a “Document” class in both C# and Objective-C so you can see the differences side-by-side. Let’s start with a quick overview of Objective-C.

What is Objective-C?

Objective-C is the main language used for developing application on Mac OS X and iOS platforms. It is a set of object-oriented classes built on top of C, therefore you can also use C code within an Objective-C Class.

Objective-C is quite different from C#, but there are some similarities. Objective-C isn’t nearly as scary as many people think. Sure, it can be a hassle doing things like manual memory management, but once you understand the patterns, it becomes second-nature. I even think it helps you to consider the lifetime of your objects more and reduce the scope of your objects, which can help improve code design.

Classes

An Objective-C class has both an interface and an implementation. These are usually stored in separate files (ClassName.h for interface, ClassName.m for implementation). The interface defines the instance variables, properties and methods your class has. The implementation is where the methods are implemented. It’s worth noting that an Objective-C interface is not the same as an interface in C# – instead it’s part of the class declaration itself.

Here is an example of a our Document class definition:

C#:

// Document.cs
public class Document
{
    public Document(string title)
    {
        // Initialise properties, etc.
    }
}

Objective-C:

// Document.h
@interface Document : NSObject

- (id)initWithTitle:(NSString *)aTitle;
@end

// Document.m
@implementation Document

- (id)initWithTitle:(NSString *)aTitle {
    if((self = [super init])) {
        // Initialise properties, etc.
    }
    return self;
}
@end

Init methods are used as object constructors. They return an instance of the object. The “id” return type is a dynamic type and can refer to any type of object. We also ensure that the super object has successfully returned a new object before setting any properties.

Objects and Memory

You may have heard that Objective-C requires you to manually manage the memory for objects. This is really not has bad as it sounds. We simply have to be aware of the scope of our objects and “release” them soon as we’ve finished using them.

To create an instance of a class we need to allocate and initialise a block of memory for it on the heap:

C#:

Document document = new Document("My New Document");

Objective-C:

Document *document = [[Document alloc] initWithTitle:@"My New Document"];

If you don’t come from a C background, you may be wondering what the * symbol is all about. Well, this tells us that we’re using a “pointer” to the object. This is similar to reference types in .NET. We refer (or “point”) to the location of that object in memory, not to the object itself. For values types (BOOL, int, etc), we don’t need to use a pointer, as we have a copy of the value itself. For more information here is a good intro to pointers.

Although the Objective-C code above will work, it will cause a memory leak unless we clean up properly. For every object you allocate, you must remember to release that memory afterwards by calling the release method on the object:

Document *document = [[Document alloc] initWithTitle:@"My New Document"];
// Do some stuff...
[document release];

You can also “retain” an object. This is used to ensure an object that was passed to you won’t be cleaned up before you are done using it.

Objective-C uses something called reference counting to handle memory. When you allocate or retain an object, the reference count is increased by one for that object. Each time you release the object, the reference count decreases by one. When a release causes the reference count to reach 0, then dealloc is called and the object is removed from memory.

If you don’t want to manually release an object from memory, you can set it to “autorelease”:

Document *document = [[[Document alloc] initWithTitle:@"My New Document"] autorelease];
// Do some stuff...
// No need to manually release

This is useful when you return an object from a method and you don’t want to burden the caller with releasing the memory for that object. However, autoreleased objects can cause unexpected behaviour, so you should explicitly use “release” whenever possible.

If you are developing an application for Mac OS X you have the option to enable garbage collection. Unfortunately this is not available on iOS. There are some exciting new developments in iOS 5 around memory management, which unfortunately I can’t talk about until the NDA is lifted. Suffice it to say that iOS 5 is going to make all of this a lot easier!

Update: Automatic memory management was introduced in iOS 5 via ARC (Automatic Reference Counting). It’s now possible to write Objective-C code for iOS without the need to retain and release objects. This has made things much simpler and means fewer crashes due to incorrect memory management!

Protocols

Objective-C protocols are similar to .NET interfaces; they specify a list of methods that a class can implement.

In our example the Document class has a Printing protocol in Objective-C and an IPrintable interface in C#. The Printing protocol has a Print method and an optional Preview method. The IPrintable interface only has the Print method, as C# does not allow optional methods on an interface.

C#:

// IPrintable.cs
public interface IPrintable
{
    Print();
}

// Document.cs
public class Document : IPrintable
{
    public void Print()
    {
        Console.WriteLine(@"Printing...{0}", this.Title);
    }
}

Objective-C:

// Printable.h
@protocol Printing <NSObject>

- (void)print;
@optional
- (void)preview;

@end

// Document.h
@interface Document : NSObject<Printing>

@end

// Document.m
@implementation Document

- (void)print {
    NSLog(@"Printing %@", self.title);
}
@end

Methods

Calling methods in Objective-C has quite a different syntax than C#. In fact it took me a while to get used to it. Let’s look an a comparison:

C#:

Document document = new Document();
document.Print();

Objective-C:

Document *document = [[Document alloc] init];
[document print];
[document release];

So that was quite easy. The big difference comes when you need to pass arguments. In Objective-C, the full name of a method includes the names of the arguments:

C#:

public class Document : IPrintable
{
    public bool SaveAs(string fileName, string filePath)
    {
        return true;
    }
}
...
Document document = new Document();
bool success = document.SaveAs("MyFile.txt", "C:\Temp");

Objective-C:

// Document.h
@interface Document : NSObject<Printing>

- (BOOL)saveAs:(NSString *)fileName toPath:(NSString *)filePath;

@end

// Document.m
@implementation Document
...
- (BOOL)saveAs:(NSString *)fileName toLocation:(NSString *)filePath {
    // Add code to save file to path...
    return YES;
}
@end
...
Document *document = [[Document alloc] init];
BOOL success = [document saveAs:@"MyFile.txt" toLocation:@"~/Temp"];
[document release];

So we don’t have a method called “SaveAs” that takes two parameters, instead we have a method called “saveAs:ToLocation:” that includes the two arguments. It’s a bit confusing at first, but gets easier the more you do it.

In Objective-C we usually say we are “sending a message to an object” rather than “calling a method on that object”. In the case above we are sending a print message to our document object. It’s more of a naming convention but it does help you to understand how those messages are handled. For instance you can send a message to a nil object without consequence:

Document *document = nil;
[document print]; // Doesn't cause an error

In .NET however, calling a method on a null object would cause a NullReferenceException.

Properties

Objective-C has properties much like C#. They are declared on the class interface using the @property keyword. The purpose of a property is to encapsulate access to data within an object. This is done using getter and setter methods. We can tell the compiler to create the getter and setter methods for us by using the “synthesize” keyword. This also generates an instance variable that holds the assigned value.

C#:

public class Document : IPrintable
{
    public string Title { get; set; }

    public Document(string title)
    {
        this.Title = title;
    }
}

Objective-C:

// Document.h
@interface Document : NSObject<Printing>

- (id)initWithTitle:(NSString *)aTitle;
@property (nonatomic, copy) NSString *title;

@end

// Document.m
@implementation Document

@synthesize title;

- (id)initWithTitle:(NSString *)aTitle {
    if((self = [super init])) {
        self.title = aTitle;
    }
    return self;
}

- (void)dealloc {
    [title release];
    [super dealloc];
}
@end

The @property declaration defines storage mechanics. In this case we’re saying we want to “copy” the string instead of keeping a pointer to the original. The “nonatomic” keyword means the getter and setter methods that are generated are not thread-safe, but are considerably faster.

Properties are useful because they automatically handle releasing the old object and retaining the new object. Because a property retains the object that is assigned to it, you need to release the property in the dealloc method. It’s also important to ask the superclass to do its cleanup.

Categories

We use Categories in Objective-C to add functionality to a class without the need for inheritance. This behaviour is similar to extension methods in C#. This is useful for adding functionality to classes you don’t own, such as the NSString class.

Here is an example of a category added to the Objective-C NSString class which reverses a string and similar functionality added as an extension method to the .NET System.String class:

C#:

public static class StringExtensions
{
    public static string Reverse(this string s)
    {
        char[] arr = s.ToCharArray();
        Array.Reverse(arr);
        return new string(arr);
    }
};

Objective-C:

// NSString+Reverse.h
@interface NSString (Reverse)

- (NSString *)reverse;

@end

// NSString+Reverse.m
@implementation NSString (Reverse)

- (NSString *)reverse {
    NSMutableString *reversedStr;
    int len = [self length];

    reversedStr = [NSMutableString stringWithCapacity:len];

    while (len > 0)
        [reversedStr appendString:
         [NSString stringWithFormat:@"%C", [self characterAtIndex:--len]]];

    return reversedStr;
}
@end

The “reverse” method now appears on instances of our String classes:

C#:

Document document = new Document("My New Document");
Console.WriteLine(document.title.Reverse());

Objective-C:

#import "NSString+Reverse.h"
...
Document *document = [[Document alloc] initWithTitle:@"My New Document"];
NSLog(@"Reversed title: %@", [document.title reverse]);
[document release];

More information

That was a basic run-down of some core differences between .NET/C# and Objective-C. Here are some useful resources for learning Objective-C:

http://designthencode.com/scratch/
http://cocoadevcentral.com/d/learn_objectivec/
http://www.otierney.net/objective-c.html

If you’d like to know more about Objective-C or iOS development, I’d be happy to continue with some more posts on this topic. Please feel free to post any questions or comments below.

Fear

Since leaving the safety of corporate life and starting a business, I often have feelings of fear. Fear of the unknown road ahead, fear of what people will think if I don’t succeed, fear of not making enough money. Whenever I start to feel this way, I begin to feel stressed, demotivated and think that I’ve made a terrible mistake. But it only takes one moment of insight, reading one inspiring article or just talking to someone about an idea, then the passion kicks in and defeats the fear. Just like that. I now realise this fear is only thoughts and there is no real situation here to be fearful of.

Thoughts are not experiences

There is a difference between real fear and simply feeling scared. Fear is a natural survival instinct. If you come across a man-eating lion, it is natural to feel fear. Adrenaline pumps into your veins and your heart-rate increases to prepare you to flee for your life. These days we don’t normally have to fear man-eaters on a day-to-day basis (unless you count your boss). This residual instinct has been translated into us feeling the symptoms of fear whenever we face an uncertain situation. Feeling scared is often irrational. Our mind likes to make up scenarios in order to prepare us for some improbable future event. Unfortunately this often inhibits our sense of what really is and causes us to make up conclusions based on nothing more than day-dreams.

You can always cope with the present moment, but you cannot cope with something that is only a mind projection – you cannot cope with the future. – Eckhart Tolle

So if you have dreams you aren’t following, or ideas you aren’t pursuing because your mind is making excuses for you, try to put your thoughts into perspective. After all, they can’t eat you.

Go Out and Create

Last week I attended the annual Webstock conference in Wellington, New Zealand. I have attended several tech conferences in recent years, but this one was by far the best. The calibre of speakers, quality of presentations and attention to detail was incredible. Everything from the opening video presentation to the program guide was beautifully crafted. Most conference swag I receive quickly gets relegated to gym-gear, but I’ll be wearing my coveted Webstock 2011 bag with pride!

Webstock, started back in 2006, attracts high-profile speakers from all over the world that give interesting and inspirational talks about everything Web-related. It’s not just about the technology, but also what it means to apply that technology to our daily lives. How the web impacts the lives of non-techies was clearly demonstrated in presentations by Amanda Palmer and Jason Webley – two musicians who talked about how the web has enabled them to manage their careers, interact with fans and reach audiences around the world.

I won’t cover all the talks here, as this has already been done, including this excellent report by Chris Barton from the NZ Herald.

It was not just the speakers that made Webstock so great. During the two-day conference, creative people from all over the country gathered to share ideas and experiences.

For me, the message from the conference was nicely summed-up in the closing remarks by organiser Natasha Lampard:

“Everything you learn is a means to an end. The end is actually getting out there and doing something with it.”

Many people come up with great ideas. Few act on those ideas and actually go out and create something. It’s too easy to sit back and over-analyze an idea. Sometimes fear can take over and you begin to think your idea is not “good enough”. I know this has happened many times to me.

“What you actually do within 24 hours of having a creative idea will spell the difference between success and failure” – Buckminster Fuller.

If you have a great idea, go out and start creating it – now! Talk to people, get feedback and refine the idea. Don’t keep it to yourself for fear that others may steal your idea. Ideas themselves are worthless, it’s the execution that matters.

In the words of presenter Jason Cohen:

“Less reading. Less worrying. More doing.”

A New Chapter

After an amazing 4 years living and working in London, my fiancé and I have moved back home to New Zealand. I learned an incredible amount as a contractor working on enterprise software development. I love software development, but I never felt fulfilled developing software for the enterprise. In my spare time I would work on my own projects, but always wished I had more time to devote to my product ideas.

So after a lot of consideration, I’ve taken the plunge and started an app development company with a good friend of mine. We will be focused mainly on creating iOS apps for the iPhone and iPad. Developing for this platform is something I truly enjoy doing and the App Store is a great place to find customers who are willing to pay for quality apps.

Last year we created and launched our first iPhone app in the App Store. We both loved the process of creating and launching a product to paying customers and improving it based on the feedback we received.

Our goal is not to grow a business with dozens of employees and large monthly overheads (I would hate that), but to simply earn enough revenue to make a decent living and have the freedom to work from where we want, for customers we care about, on products we are passionate about.

"Build a life around what you’re really talented at and you’ll be many times more successful than if you base your work on what you’re ok at." – John Williams.

I’m spending time at the moment learning about product development and researching several product ideas. I am very wary of wasting time and money creating a product that no one wants, so I’m researching ideas thoroughly before thinking about design or writing a single line of code. I will discuss this process further in my next post.

Am I worried about the uncertainty of starting a business? Of course I am – I still have bills to pay and setting up a flat in Auckland is not cheap. I know sometimes it’s going to get hard and I’m going to need passion and motivation to stick in there. But I know deep down that this is what I want to do and now is the time to do it.

Life’s too short not to enjoy what you do every day. Make 2011 the year you get paid for doing what you love. If you’re interested in taking the plunge, I highly recommend reading Screw Work, Let’s Play: How to Do What You Love and Get Paid for it by John Williams.

Refactoring To Functional Code

In my previous post I explained that some problems are better suited to a functional approach than traditional, imperative code. I showed an example of a problem that suits a functional approach and demonstrated turning several lines of imperative code with nested for-each loops and if-statements into a single line of functional code. Paul Harrington posted a comment asking what individual steps I took to refactor the code. Here’s my explanation of the refactoring:

First, here is the original, imperative method.

public int[] Translate(string word)
{
    ArrayList numbers = new ArrayList();

    foreach (char character in word)
    {
        foreach(KeyValuePair<int, char[]> key in keys)
        {
            foreach(char c in key.Value)
            {
                if(c == character)
                {
                    numbers.Add(key.Key);
                }
            }
        }
    }

    return (int[]) numbers.ToArray(typeof (int));
}

As you can see, it takes some effort to determine what’s really going on. From this code we can determine that:

For each character in a word, select the first key in the list of keys that contains the character and add it to an array of numbers to return.

Now, lets express the statement above as functional code:

To select each character in a word, we need to convert the string to an array of characters. The LINQ Select method projects each element of a sequence into a new form. In this case, a string translates to a sequence of characters:

IEnumerable<char> characters = word.Select(c => c);

For each character, we need to find the corresponding key that contains the character. The First method returns the first element of a sequence:

int key = keys.First().Key;

In our case we need the first key in the list of keys that contains the character. The First method has an overload that returns the first element in a sequence that satisfies a specified condition.  To specify our condition we use the Contains method, which determines whether a sequence contains a specified element:

char c = 'a';
int number = keys.First(k => k.Value.Contains(c)).Key;

When we combine the code that selects each character with the code that gets the first key containing the character, we end up with this:

IEnumerable<int> numbers = word.Select(c =>
        keys.First(k => k.Value.Contains(c)).Key);

Finally, we use the ToArray method to return an array of type int. Now we have our final, refactored method:

public int[] Translate(string word)
{
    return word.Select(c =>
        keys.First(k => k.Value.Contains(c)).Key).ToArray();
}

I hope this helps to explain the steps I took to refactor imperative code to functional code. You can get really clever with functional code, but remember, readability is what’s most important. Sometimes it’s best to stick with good old-fashioned for-loops and if-statements, but for some problems, like above, a functional approach can lead to more readable, clean and concise code.

An Example of Functional vs Imperative Programming in C#

Last week I went to a talk presented by Mike Wagg and Mark Needham from ThoughtWorks on Mixing Functional and Object-Oriented Approaches to Programming in C#. Mike and Mark discussed using a functional approach with LINQ to solve problems in C#.

I have come to realise lately that some problems are much better suited to a functional approach than traditional imperative programming. Many problems that involve selecting, filtering or performing actions on a list of items are best suited to functional programming, which can significantly reduce the amount of code required to solve the problem.

Here is a simple example of a problem that is best solved with a functional rather than an imperative approach.

Some businesses advertise their phone number as a word, phrase or combination of numbers and alpha characters. This is easier for people to remember than a number. You simply dial the numbers on the keypad that correspond to the characters. For example, “1-800 FLOWERS” translates to 1-800 3569377.

We will write a simple program that translates a word into a list of corresponding numbers.

phone-keypad

First, let’s start with a dictionary that contains each number and the corresponding characters:

private readonly Dictionary<int, char[]> keys =
            new Dictionary<int, char[]>()
                {
                    {1, new char[] {}},
                    {2, new[] {'a', 'b', 'c'}},
                    {3, new[] {'d', 'e', 'f'}},
                    {4, new[] {'g', 'h', 'i'}},
                    {5, new[] {'j', 'k', 'l'}},
                    {6, new[] {'m', 'n', 'o'}},
                    {7, new[] {'p', 'q', 'r', 's'}},
                    {8, new[] {'t', 'u', 'v'}},
                    {9, new[] {'w', 'x', 'y', 'z'}},
                    {0, new[] {' '}},
                };

Next, we create a Translate method that takes a word and returns an array of corresponding numbers.

With a traditional, imperative approach, we would use for-each loops and if-statements to iterate through characters and populate an array of matching numbers:

public int[] Translate(string word)
{
    ArrayList numbers = new ArrayList();

    foreach (char character in word)
    {
        foreach(KeyValuePair<int, char[]> key in keys)
        {
            foreach(char c in key.Value)
            {
                if(c == character)
                {
                    numbers.Add(key.Key);
                }
            }
        }
    }

    return (int[]) numbers.ToArray(typeof (int));
}

Alternatively, with a functional approach we can use LINQ to select elements from the dictionary and transform the output to an array of matching numbers:

public int[] Translate(string word)
{
    return word.Select(c => 
        keys.First(k => k.Value.Contains(c)).Key).ToArray();
}

And there you have it. Several lines of nested for-each loops replaced with a single line of succinct functional code. Much nicer!

If You Must Rewrite

As a general rule, you should never rewrite your software. I have (barely) survived several rewrites in the past and they all shared the same horrible experience:

  • The rewrite took much longer than expected, during which time the business stood still while the market moved on.
  • Functionality written over several years had to be re-implemented in a fraction of the time.
  • The development team was immediately pressured to “get it done”. This created a sense of always being behind schedule.
  • The business became frustrated and could not understand why it was taking so long.
  • The rewrite provided little or no new functionality to the business.
  • There were hidden business rules that had been long forgotten and no one knew what they meant.
  • The old system could not be turned off until all the features were migrated to the new system.
  • The old system still had to be maintained while the new system was under development.

There has been plenty written about the problems with software rewrites. Here are some great articles on the subject:

The general consensus from each of these articles is to never rewrite software unless you really have to.

So when do you really have to rewrite? I mean reeeeaaally have to. Well, there are times when a rewrite is completely unavoidable. In one such case I came across recently, the company no longer had access to the source code of their core product. That’s a pretty tough position to be in and a rewrite is pretty much the only option for moving forward.

So, here are a few retrospective tips from my experience enduring rewrites. This is not a prescriptive list and is only meant to represent ideas that might have helped in the cases I was involved in.

If you must rewrite…

The rewrite will always take longer than you think. Be prepared for a lot of work. An effective strategy is crucial – time spent rewriting the system is time lost from adding new features to grow the business.

Involve the product owner. They will be eager to complete the rewrite as it is costing them money to re-implement functionality they already have. Have them on-hand to prioritise features and answer questions. Keep them aware of progress.

Identify the core set of features the business can not function without. Focus on these features and plan to release as soon as you have a minimum feature set.

Prioritise the features. Ensure you are always working on the highest-priority feature.

Limit work in progress. Don’t try to re-implement everything at once. Complete a feature before moving onto the next.

Don’t rewrite everything. Be harsh – throw out anything you don’t absolutely need. Remember, every feature you rewrite costs adding a new feature that could grow the business.

Simplify your business processes. Use this as an opportunity to refine and simplify your existing business processes. Don’t just re-implement a feature because “that’s how it works in the old system”.

Use a well-known, established technology. Don’t be tempted to use the latest and greatest just because you get to start over. Speed is the key here, you don’t want to be thrashing with an unfamiliar technology.

Release as soon as possible, but not a moment sooner. Your current customers won’t be happy if the new system doesn’t function correctly or important features are missing.

Migrate existing data early. Don’t leave data migration to the last minute. You need to know your new system can work with the data you currently have. I was once involved in a rewrite where the migration happened at the last minute – the entire system failed to function and we lost more time rewriting parts to improve performance.

Implement whole features at a time. Don’t focus on horizontal layers of the application, e.g. database layer, services, UI, etc.

If you can, replace parts of your system at a time. If you can rewrite parts of the new system that integrate the old system, then you can stagger the rewrite and release sooner.

Use off-the-shelf software. If you have a generic feature, such as a forum or CMS, consider using a commercial or open-source alternative to avoid reinventing the wheel.

Don’t create a mess. Write adequate tests. The only way to go fast is to go well. Buggy software will cost more time and money, even in the short-term.



Follow

Get every new post delivered to your Inbox.