Memory Management Pitfalls in Xamarin iOS - Introduction
June 16, 2013
Writing iOS apps in Xamarin.iOS is a wonderful thing. You get all the beautiful benefits of creating native applications for iOS, but in a language that’s both comfortable and powerful – C#. What’s not to like about using all of the baked in language features of C#? LINQ, generics, extensive base class libraries, async support, elegant syntax, garbage collection – it’s all there. And it’s all good.
…Except when it’s not. Remember, it’s still Objective C’s world, Xamarin just lets us play in it with C#. Getting too comfortable in C# world can lead to some pitfalls that should to be known and avoided. This will be the start of a series of posts detailing some gotchas when it comes to Xamarin.iOS and memory management/garbage collection issues.
First and foremost, we must remember that while Xamarin.iOS is garbage collected, Objective C is not. Objective C uses reference counting to manage the lifetime of its objects. It is where these two worlds collide that gets us into trouble, particularly when we’re dealing with UI classes – things derived from UIView.
The “wrapper” classes for UI classes on the Xamarin.iOS side purposely hold a reference to their native counterpart. This means that the managed UIButton wrapper (for instance) holds a pointer to the native/Objective C UIButton object to keep it “alive” (retain it) until we’re done using it. Xamarin keeps track of the overall reference count to the managed wrapper object, and as we’ll see later also handles things differently between their wrapper UI types (UIButton) and user types that are derived from those wrapper types. This reference counting can lead to “too high” reference counts to release an object, and/or cyclical references with the same result – objects not being released.
For more background on this interaction between the managed and unmanaged world, and garbage collection in general, here is an excellent video (with accompanying slides) of a talk by Mark Probst and Rodrigo Kumpera at the 2013 Xamarin Evolve conference.
Reference cycles and/or an increased reference count of the native object are surprisingly easy to create by accident in our C# code. In the following series of posts, we’ll take a look at a few examples.