In this article

New Reference Counting System in Xamarin.iOS

10/1/2018

2 minutes to read

Contributors

In this article

Xamarin.iOS 9.2.1 introduced the enhanced reference counting system to all applications by default. It can be used to eliminate many memory problems that were difficult to track and fix in earlier versions of Xamarin.iOS.

Enabling the New Reference Counting System

As of Xamarin 9.2.1 the new ref counting system is enabled to all applications by default.

If you are developing an existing application, you can check the .csproj file to ensure that all occurrences of MtouchUseRefCounting are set to true, like below:

<MtouchUseRefCounting>true</MtouchUseRefCounting>

If it is set to false your application will not be using the new tooling.

Using older versions of Xamarin

Xamarin.iOS 7.2.1 and above features a enhanced preview of our new reference counting system.

Classic API:

To enable this new Reference Counting System, check the Use the reference counting extension checkbox found in the Advanced tab of your project's iOS Build options, as shown below:

Note that these options have been removed in newer versions of Visual Studio for Mac.

The new reference counting extension is required for the Unified API and should be enabled by default. Older versions of your IDE may not have this value checked automatically and you might have to place a check by it yourself.

Important

An earlier version of this feature has been around since MonoTouch 5.2 but was only available for sgen as an experimental preview. This new, enhanced version is now also available for the Boehm garbage collector.

Historically there have been two kinds of objects managed by Xamarin.iOS: those
that were merely a wrapper around a native object (peer objects) and those that
extended or incorporated new functionality (derived objects) - usually by keeping
extra in-memory state. Previously it was possible that we could augment a peer
object with state (for example by adding a C# event handler) but that we let the
object go unreferenced and then collected. This could cause a crash later
on (e.g. if the Objective-C runtime called back into the managed object).

The new system automatically upgrades peer objects into objects that are
managed by the runtime when they store any extra information.

This solves various crashes that happened in situations such as this one:

Without the reference count extension this code would crash because cell
becomes collectible, and so its TouchDown delegate, which will translate
into a dangling pointer.

The reference count extension ensures the managed object stays alive and prevents
its collection, provided the native object is retained by native code.

The new system also removes the need for most private backing fields used in
bindings - which is the default approach to keep instance alive.
The managed linker is smart enough to remove all those unneeded fields from
applications using the new reference count extension.

This means that each managed object instances consume less memory than before.
It also solves a related problem where some backing fields would hold references that
were not needed anymore by the Objective-C runtime, making it hard to reclaim
some memory.

Feedback

We'd love to hear your thoughts. Choose the type you'd like to provide: