My experience with MonoTouch has generally been very positive.
Why I love MonoTouch:
- C# goodness, especially event handlers instead of overly verbose ObjC delegates
- It's fun to port ObjC loops to oneliners using LINQ and lambdas
- I prefer somewhat ugly MonoDevelop to pretty-but-very-odd Xcode
- I can reuse both C# and ObjC code, and ObjC code is straightforward to port, if needed
- Xamarin support is friendly and helpful
There are some things that annoyed me:
- Some generic-heavy C# code will crash the device due to AOT limitations—learned it the hard way
- MonoDevelop hangs for a few seconds after you switch from Xcode, even if you didn't change anything
- You need to make sure you _understand_ how MonoTouch GC works together with ObjC reference counting, or you'll get memory leaks
- You'll need to learn to use Instruments to find those memory leaks
- Debugger often freezes (should've reported this)
- Binaries can get heavy, but not too heavy
- Compilation is impossibly slow on Air, barely tolerable on Pro
- Lack of tooling for binding ObjC code—I wish I could just drop ObjC files and headers into a MonoTouch binding project instead of compiling it to fat binary first
- You need to make sure you _understand_ how MonoTouch GC works together with ObjC reference counting, or you'll get memory leaks
- You'll need to learn to use Instruments to find those memory leaks
Interesting, reading that makes it sound like a C# developer that wants to work with MonoTouch will have to verge off to learning at least some Objective C if they want to have shippable code. The coder side of me is always up for learning a new language but if shipping was my utmost concern I'd want to get right to coding in C# and let MonoTouch take care of the rest. That doesn't appear possible.
How much time do you think a C# developer with several years of experience would need to put into learning the ins and outs of ObjC memory management before their code could be considered close to production level?
Interesting, reading that makes it sound like a C# developer that wants to work with MonoTouch will have to verge off to learning at least some Objective C if they want to have shippable code.
Yes, you'll definitely need to learn some things about Objective C. This isn't really about learning the language itself though. It's more about understanding iOS and ObjC runtime.
The closest analogy to C# develop would be COM and P/Invoke. C# provides tools to interface with COM and native libraries, but you still need to learn some marshalling fundamentals so you can ensure GC doesn't collect objects while they are being used by native code, you need to implement IDisposable and not forget to free unmanaged resources, etc.
It's similar with MonoTouch: you need to understand that MonoTouch classes “wrap” native objects, that disposing of wrappers doesn't necessarily kill native objects because other native objects may still link to it, and that sometimes GC can't know for sure if an object is eligible for killing, and will never collect it.
In general, this comes down to: don't rely on .NET GC to kill native objects, do it yourself. My life got so much better after I started doing so.
Things that confused me most (and which are all you really need to know about ObjC memory management):
How much time does it take to learn this? No more than a week. But it takes more to find memory leaks in existing app so it's better to get some understanding and learn to profile early. For me, “fixing” a two-month-old codebase took about week and a half.
If I could give advice to myself when I started writing production code in MonoTouch without any experience with it, it would be: “Don't Guess. Profile.”
For example, I spent a lot of time making sure I don't load heavy .NET objects, but most memory crashes went away when I started using JPG instead of PNG pictures in a picture-heavy app.
Then it got a lot better when I took time to learn about best iOS practices such as keeping a pool of about ten reusable views and re-filling them with new content as they go offscreen when the user is scrolling, instead of creating hundreds of views at once. What is really nice, iOS6 UICollectionView class enforces this memory usage pattern by providing a neat API with view pool. Use it instead of rolling out your own collection view.
Another hard lesson was to never block UI thread and do any computational intensive stuff such as parsing JSON in .NET Tasks on another thread. This is obvious in retrospect, but I thought parsing JSON wasn't intensive. It was.
Finally, if your app crashes randomly, it's most probably your fault! I really need to stress it because I fell into this trap, thinking MonoTouch is buggy when my app crashed every minute. Turned out, it had insane memory leaks and aggressively allocated large amounts of memory at once—but I didn't bother to learn about “right” techniques until it was too late. Learn to profile early so you don't panic later.
Thank you for taking the time to provide these tips and links. Lots of good info here that I'm sure I'll be referring back to in the not too distant future.
- C# goodness, especially event handlers instead of overly verbose ObjC delegates
- It's fun to port ObjC loops to oneliners using LINQ and lambdas
- I prefer somewhat ugly MonoDevelop to pretty-but-very-odd Xcode
- I can reuse both C# and ObjC code, and ObjC code is straightforward to port, if needed
- Xamarin support is friendly and helpful
There are some things that annoyed me:
- Some generic-heavy C# code will crash the device due to AOT limitations—learned it the hard way
- MonoDevelop hangs for a few seconds after you switch from Xcode, even if you didn't change anything
- You need to make sure you _understand_ how MonoTouch GC works together with ObjC reference counting, or you'll get memory leaks
- You'll need to learn to use Instruments to find those memory leaks
- Debugger often freezes (should've reported this)
- Binaries can get heavy, but not too heavy
- Compilation is impossibly slow on Air, barely tolerable on Pro
- Lack of tooling for binding ObjC code—I wish I could just drop ObjC files and headers into a MonoTouch binding project instead of compiling it to fat binary first
But still, I'm glad we went with MonoTouch.