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.