in iOS

iPhone from A Game Developer’s Perspective: Objective C

I have a feeling I don’t fit the profile for the average iPhone developer. I bet a lot of them come from Mac or Web development backgrounds. On the other hand, I come from over the years of professional game development on consoles and PCs, which gives me a different perspective on things. When I hear developers complaining about Apple’s approval process to put something on the App Store, I can’t help but laugh and wish they had a taste of submitting an Xbox or PS3 game for approval. Now, that’s a real bitch! On the other hand, long-time Mac developers will be throwing around all these API names and classes like everybody learned them in kindergarden.

I’ve only been doing iPhone development for a few months, so I don’t claim to know everything. But they have been some intensive couple of months, that’s for sure. This is my attempt to share my experiences, and hopefully encourage more game developers to take the leap and consider this really fun little machine.

As I explained in a previous post, I was a Mac-virgin. Sure, I had used one here and there, but never as my primary platform. Not only was I able to get up to speed and functional in a matter of days, but I totally love it and switched to it as my main computer. So, with that out of the way, how about the iPhone development itself? Over the next few days (or weeks, depending how busy I get), I’ll try and cover the major areas of iPhone development that I’ve experienced so far.

Let’s get the most obvious one out of the way: Objective C.

Somehow, its very mention seems to fill people with fear. When other programmers hear I’m doing iPhone development, they lower their voice, they get closer, and ask “Do you _have_ to write it in Objective C?” I think the main reason people are scare of it is because it’s not very well known. It’s not a sexy newcomer that the web is buzzing about like Rails, or a language with the backup of corporate giants like C# or Java. Objective C has been around since the early 80s, which is pretty amazing because it feels very modern in a lot of its features. Frankly, I’m surprised that Microsoft chose to create C# instead of adopting/extending Objective C (or maybe I’m not that surprised coming from Microsoft–OK, that was the last dig at MS and C# for today. Promise).

I had never used Objective C before I started doing iPhone development, but it was a breeze to get up to speed coming from a strong C and C++ background. The most important thing is that the interop between Objective C and C/C++ is nearly flawless. It’s a pleasure to call Objective C functions from C++ and the other way around. So much so that the lines get all blurred between what is what. Take that C#! (oops, so much for my promise).

Objective C is organized like C++, with header files and implementation files. That’s both good and bad. Good because it’s familiar, it gives you a good separation between the public interface of a class and its implementation, and allows for fast build times. But it’s bad because there is some annoying duplication between both files. Fortunately, Objective C gets this one right (again), and allows you to keep the header file to purely the public interface of the class. That means I can declare all the private member functions in the implementation file, which keeps duplication to a minimum.

A word of warning: You’ll probably have to change all your .cpp files to be .mm so they compile as Objective C and you can freely include any Objective C headers. Also note that Objective C files are usually .m which only parses C header files. If you need to call C++ files you need to make them .mm, or you’ll get some really bizarre errors.

If you’re really a died-in-the-wool C++ fanatic, you can isolate yourself from all the Objective C stuff by writing a few wrappers that interface with the operating system. If not, you can go with the flow and embrace it and use it when it’s needed.

Assuming you’re willing to look at Objective C, how is it coming from a C++ game programming background? At first glance it’s a bit ugly. I admit it. It looks like it’s full of – and + and [[square:brackets] everywhere]. But it’s very superficial. Objective C is a superset of C++, which means they introduced a different way to create Objective C classes (as opposed to C++ classes). The worst thing about the brackets, which are used for sending messages to objects, is that typing them is cumbersome. I often find myself having to move back to the beginning of the line to add new brackets as I’m making new function calls.

Internally things are much more dynamic than C++, and instead of member function calls they’re really messages that get passed around. That makes it easier to deal with null objects or objects that might or might not implement specific interfaces. I don’t know if you can add new message handlers on the fly, but I suspect you could (although why you’d want to do it other than for geek achievement points is beyond me–I’ve certainly never felt the need to do it).

One of the features that I’m using quite a bit are properties. You can declare member variables as properties, tag them with what kind of access is permitted (read-only, read-write, whether you want to take ownership or not, whether it’s an atomic assignment, etc), and all the code is automatically provided for you. Nice time saver.

Protocols are also a nice, clean way to provide interfaces. Certainly much better than the madness of C++! It makes working with objects that implement certain interfaces very easy. It’s also really easy to pass “pointers” to specific member variables through the use of selectors.

Enough with the raving. What’s not to like? Only a couple of things, really. Or at least so far. Ask me again in a year and I’ll probably have a laundry list of complaints. I doubt it will ever reach my level annoyance with C++ though. That’s pretty much impossible.

My biggest complaint about Objective C is that, get this, C++ constructors for member variables in Objective C classes are not called. Yup. You read that right! I’m sure there’s a good reason, but it does suck. Fortunately most of the Objective C code is high level classes, so it’s OK to new the C++ classes I need to work with. Still, it’s annoying. I also wish that Objective C played better with namespaces, but that’s a relatively small complaint.

This might sound like a strong statement, but if I were to design my ideal development language today, it would be pretty darn close to Objective C.

Something I still don’t know much about: Performance. I haven’t been doing much profiling on the iPhone yet, and all my performance-sensitive parts are written in C++. Still, I’d be curious to see how much overhead Objective C adds on top of C++. I suspect that a fair bit given the message-passing architecture and the more dynamic nature of the language.

Someone asked me what am I using for unit testing with Objective C. Hmm… errr… I’m not doing any unit testing in Objective C. There I said it 🙂 Not yet anyway. I’m sure I will as soon as I start using more of it. Most of the Objective C code is high-level code interfacing with the iPhone API, so I haven’t felt much the need to use TDD with it. If anybody has some recommended Objective C unit-testing frameworks that are lightweight and minimalistic, I’d love to hear it.

If you’re interested in learning Objective C, this document was the best resource I found to learn Objective C. It’s simple enough that you can use it to get up to speed, but detailed enough that I still refer to it from time to time. I haven’t felt the need for any books or any other tutorials.

Coming up next: The iPhone API, Xcode, and more goodies.

  • I have been a fan of your writings since you were still at High Moon, I could never actually apply the knowledge gained here (yeah, sure, call me lazy 🙂 ) because I have yet to get my break in game development industry (have been coding all sorts of other stuff 😉 ), but it’s great to see you developing on iPhone. I would be looking forward to how you do TDD on iPhone and other agile practices.

    As for TDD, A framework that I saw frequently in google queries is GTM (http://code.google.com/p/google-toolbox-for-mac/) and RSpec (it’s in Ruby, I don’t think Unit Testing Framework should require one to learn a different language). I just downloaded GTM and its own “All Unit Tests” target takes 6+ seconds on this Mac Mini (can’t afford a better machine). Would really be interested in what framework you choose and how you keep build times low.

    BTW, thanks for all that raving on Objective C, it encouraged me to actually go ahead and really learn it (I started iPhone a few months ago and have been coding by blind instinct 😉 )

    Thanks for the great read.


    MI

  • Oh, don’t get me wrong. I *am* doing TDD on the iPhone. I wouldn’t dream of doing anything complicated without TDD. It’s just that I’m not using it for the Objective C part. I’m sure that as I use more and more Objective C, I’ll start doing TDD there as well, but not yet.

  • “I wouldn’t dream of doing anything complicated without TDD.”

    Of course you won’t, I never said that, am just excited to see when you start doing it.

  • Charles Nicholson

    It’s like you’re -begging- me to chime in about Obj-C vs C#!

    Microsoft didn’t prefer to embrace/extend/extinguish Obj-C over C# for the same reason that Sun didn’t prefer Obj-C over Java. They’re fundamentally different languages that fill different niches and serve different purposes.

    Obj-C (and Obj-C++), because they are supersets of C and C++, are down-to-the-metal systems programming languages that allow for raw memory access, unverifiable code, and all the things that let you blow your legs off in the quest for performance. They’re great languages, don’t misunderstand me, but the “Obj-” parts (interfaces, protocols, selectors, messages, the sort-of introspection) of them are a relatively lightweight architecture that runs on a relatively lightweight runtime on top of C/C++. You compile them down to platform-specific executables that can only run on the specified target architecture, and they yield static binaries.

    C# and Java are higher-level languages that revoke raw memory access and run fully sandboxed inside VMs. Executables come in platform-independent compiled bytecode packages, they are verifiable, much easier to prove secure, and have significantly more powerful reflection/introspection services. A few basic caveats notwithstanding, programmers generally only consider algorithmic complexity when optimizing C#/Java programs. The entire “power-user” layer of C/C++ programming is revoked in exchange for simpler syntax, less bookkeeping, and generally terser programs.

    Obj-C and Obj-C++ can’t be transformed to meet this goal without removing the C/C++ parts of them that allow for raw memory access. They’re not “bad” languages, I’m not sure that’s even a well-formed statement, they just serve fundamentally different purposes.

  • Charles, you’re right about C# and Objective C having different goals and needs. I was just speaking from my point of view as a user of both languages. Frankly, for 99% of my use, I don’t care that C# runs inside a VM. I’m not sure how many game developers to. I just use it as a higher-level language for rapid development of non-performance critical tools. From that perspective, Objective C and C# start looking very similar.

  • Frederic

    As a programmer of non-performance but critical tools, that need to be used by quite a bunch of people or servers for several years, I care very much about my stuff being as stable (and easy to maintain) as possible. In this respect, anything based on C or C++ sounds like potential trouble to me, it’s just way too easy to screw up with these languages.

  • Hi Noel,

    You might want to take a look at http://developer.apple.com/iphone/library/codinghowtos/Tools/index.html#GENERAL-ENABLE_OBJECTIVE_C___COMPILATION to enable objective-c++ compilation and keep your cpp file extension (especially when writing cross-platform code). But pay attention to a typo in this FAQ… You will have to use “-x objective-c++” instead of the mentioned “-x objectiveC++”.

  • Thanks, Ramses. That’s a pretty cool trick. It sure beats changing all file extensions to mm!

  • I’m also new to the iPhone and Objective-C development. The approach I’ve taken thus far minimizes the amount of interaction between my ObjC and C++ code. As you mentioned, C++ constructors are not called for C++ member variables inside of ObjC classes and require using pointers and new (I found this annoying as well). If you limit your mixing of C++ and ObjC to allocating C++ member variables via new and calling member functions via those pointers, the only files that need the .mm extension are the Objective-C (or more correctly, Objective-C++) implementation files that include C++ header files (directly or indirectly via an ObjC header). This makes porting existing code a bit easier (no fiddling with file extensions, just focus on learning enough ObjC to create a layer to interface with the iPhone and OpenGL ES changes).

  • For those who are interested in iPhone development using Objective C++, there’s an article on our blog about this topic. It got some pretty interesting numbers concerning performance of Objective C versus C++ and iPhone versus desktop computers.

  • Kim

    I think Objective-C allows compatibility to C++ for its conveniency, not for serious developing with mutation in its part.
    As my experience of 23 years in C++, all things follows the same.

    I am sure that Objective-C would dominate at some extent over C++/C or others in long term as C++ had done during 23 years!

    For my case recently I had given up using C++ but Objective-C.   If I need other than Objective-C, I would go for C# rather than C++!

  • Jacopo Santoni

    Objective-C is great, the only real problem that I had during my iPhone developing experience is performance. I’m used to develop in C/C++ but when I started developing on the iPhone I thought that I wanted to give Objective-C a chance (even because it’s absolutely needed for their API). Really easy to learn and to use, but when I started translating some bottlenecks from Objective-C to C++ with STL I realized that things were really slow. And with slow I mean like 10 times slower, comparing the same identical code, without using ObjC collections but STL and without using the creepy objc_msgSend (ok, not so creepy, but called many times).

    I like ease of development, but I do like elegant and performant code so I preferred to switch back to C++ as much as possible. Specific things are really clumsy in my opinion, especially regarding game development in which you may require to work with many small C structs and you are forced to wrap them into NSValues to use collections. This, as well as many little things that just made source code less enjoyable from my personal point of view.

    Then you know, everyone has a different taste, but since source code is like a book, if I don’t like the language I’m using and I can change it, why not? I want to be pleased when I read it. 🙂