A couple years ago tablet computers were seen mostly as a novelty or consumer toy. But recently a major shift has been occurring in the business world. Many consulting companies that traditionally write line-of-business applications in XAML, Flex, or HTML have suddenly found themselves with an overwhelming demand for iPad applications. Not just toys either, there are a lot of projects gearing up with price tags in the hundreds of thousands or even millions of dollars. While .NET and Java will still be viable back-end platforms for years to come, there are a lot of opportunities for teams that are willing to cross-train.
We spoke with one such developer, Somya Jain, about moving from C# to Objective-C.
Somya Jain: First thing that I learnt (and I learnt it the hard way) was mobile development is significantly different from server side or desktop development. Mobile devices have less RAM, a slower network, smaller screen and a slower CPU! Yet there is an expectation for a great user experience. People can easily compare your app to another in the app store. It’s much harder to do that with your run of the mill business app.
I learnt Objective-C to build apps for iPhone and iPad. Coming from C++/Java/C# background, the learning curve was actually not too bad. Most of the concepts translate quite easily. Initially, I tried to learn by following the textbook approach and reading documentation. But, I found I learnt a lot faster when I actually took the plunge and started to work on a project.
The following are the key concepts to understand in Objective-C. While there are some similarities with C#, there are also subtle differences.
Memory Management
The first thing to tackle is memory management. Understanding alloc, release and autorelease are critical for iOS development. With the introduction of ARC this may be becoming less important. But there areas where ARC can trip you up and it helps to understand the underlying principles.
Memory management issues such as, over releasing memory, resulting in the dreaded BAD_ACCESS crash, and not releasing memory, causing memory leaks, can be hard to figure out. Yet they have a significant impact on the performance and usability of your app. Learning to quickly identify and fix these problems is critical. I recommend learning how to use NSZombies and instruments to debug these issues.
As an aside, Objective-C does support Garbage collection, however this is limited to mac osx and is not supported in iOS.
InfoQ: Adding and releasing objects sounds a lot like COM reference counting, but what is "autorelease"?
Somya: Essentially, you use autorelease when you're returning an object that will not be managed by the object that created it. By calling autorelease, the object is added to an auto release pool and is released when the pool drains. The receiving object is then responsible for retaining it if it wants to use it for anything. Here is more info from the apple docs:
The Application Kit creates an auto release pool on the main thread at the beginning of every cycle of the event loop, and drains it at the end, thereby releasing any auto released objects generated while processing an event.
InfoQ: What is NSZombies?
Somya: NSZombies can be used to detect the memory over release issue I mentioned earlier. A common scenario is an unbalanced release on an auto-released object. What happens is that, during the final release, everything works fine and the object is de-allocated, but when the auto-release pool drains (some time later), the app crashes in an attempt to auto-release a de-allocated object. The object itself is no longer around, so it's hard to figure out exactly where the problem is. This is where NSZombie objects come in, setting the NSZombieEnabled flag turns any released object into an NSZombie instead of de-allocating it. You can now set a breakpoint whenever release or autorelease is called on NSZombie objects, allowing you to spot the offending code path.
InfoQ: Can you explain what ARC is and why you think it will make memory management easier?
Somya: Essentially, with ARC enabled, the compiler automatically generates retain and release call for you. This should mean that you don't have to worry about memory management. But experience tells me otherwise. I haven't used ARC yet, so It's had for me to comment on it too much.
Method calls vs Messages.
Another subtle difference between the two languages is that, in C#, method calls are static and are bound at compile time (ignoring dynamic compilation for now). However for Objective-C messages are dynamically bound to objects at runtime time, not compile time. This means that you can send any declared message to any object and the compiler will not complain. Errors will show up only at runtime.
Interestingly, there is a mechanism to intercept messages even if the class doesn't implement them, this is generally used in advanced scenarios such as multiple inheritance, journaling, and dispatching messages to dynamically loaded code.
Thread Pool vs Grand Central Dispatch
At a high level the idea is the same, a system managed pool of threads. However, this is one area where I feel iOS really shines. Firstly, iOS supports different priority levels even with thread pools giving you finer grained control. For example you can do image loading and manipulation in higher priority thread so that a background download doesn't slow down your UI.
Another great feature is Dispatch groups that allow several tasks to be submitted and be notified only when all of them are complete.
The following items map almost one to one between C# and Objective-C
- Extension Methods (C#) <==> Categories (iOS)
- Interface (C#) <==> Protocol (iOS)
- Delegates (C#) <==> Blocks (iOS)
Some things I miss about C#
- Generics
- LINQ
- Having all my code in 1 file, and not having to create header files.
Some other tips for C# developers:
- Check out AppCode (Objective-C) from the guys that brought you Resharper (C#)
- Also MonoTouch from Xamarin brings C# for iOS devices.
InfoQ: What IDE do you prefer for iOS development?
Somya: Definitely AppCode, it brings the code completion and refactoring support that I am already familiar with, having used ReSharper. I also like that it highlights potential memory-management issues for you, it’s great for when you’re just getting started with iOS. At the end of the day it makes me more productive, so it's a no brainer.
InfoQ: You say you miss generics. Does Objective-C offer anything you can use instead or must you use untyped collections like we had in .NET 1.0?
Somya: Yes you use un-typed collection like in 1.0. But due to dynamic message binding you don’t need to cast the object in order to send it a message.
InfoQ: Are there any Objective-C features that you wish C# would adopt?
Somya: At the language level, probably not. I haven't found myself thinking, wow this would be a great feature in C#. However, at the API level, I think apple have done a good job with iOS. Even though the APIs come across as somewhat restricted, they are well thought out. For example, In the NavigationController and UITabBarController, it's a simple flag to enable an animation when navigating between views. You have to do much more work for both android and WP7.
InfoQ: How does building the user interface in iOS compare to working with WinForms or Silverlight?
There are 2 main UI libraries from apple, UIKit and GLKit. GLKit it targeted more towards opengl based apps and games. UIKit is closer to WinForms/WPF. It has standard controls like text boxes, labels, drop downs etc. These UIViews (controls in .NET speak) can be easily extended and combined to make other views similar to creating custom controls and user controls in .NET. iOS however, only supports fixed co-ordinate based layout, so you need to specify the exact size and location of each view within it's parent. I feel like a lot of the other UI concepts are similar,
- You still have a view hierarchy.
- You still need to be careful when loading data in a background thread, It still needs to be marshaled onto the main thread.
- You need to understand the view lifecycle etc.
What I miss most however is support for data binding.
About the Interviewee
After 11 years as an enterprise software developer/tech lead/architect, Somya Jain is now a freelance mobile developer (iOS, Android & Windows Phone), based in New York City. He focuses on multi-platform mobile apps.