Note: Missed last week MonoTouch 5.3 (alpha) release ? or my earlier posts on the linker vs Runtime.Arch and UI thread checks ? Read them first
MonoTouch 5.2 was the first stable release to support the --newrefcount option when --sgen (the new garbage collector) is enabled.
This new feature had a few impact on MonoTouch’s bindings. Here are examples from ATMHud‘s bindings, file AtmHud.g.cs, in the monotouch-bindings github repository. It’s a generated file so it’s not visible on github web site.
Listing 1
object __mt_HudView_var;
[CompilerGenerated]
public virtual AtmHudView HudView {
[Export ("__view", ArgumentSemantic.Retain)]
get {
AtmHudView ret;
ret = (AtmHudView) Runtime.GetNSObject (MonoTouch.ObjCRuntime.Messaging.IntPtr_objc_msgSend (this.Handle, sel__view));
if (!IsNewRefcountEnabled ())
__mt_HudView_var = ret;
return ret;
}
[Export ("set__view:", ArgumentSemantic.Retain)]
set {
if (value == null)
throw new ArgumentNullException ("value");
MonoTouch.ObjCRuntime.Messaging.void_objc_msgSend_IntPtr (this.Handle, selSet__view_, value.Handle);
if (!IsNewRefcountEnabled ())
__mt_HudView_var = value;
}
}
Listing 2
object __mt_WeakDelegate_var;
[CompilerGenerated]
public virtual NSObject WeakDelegate {
[Export ("delegate")]
get {
NSObject ret;
ret = (NSObject) Runtime.GetNSObject (MonoTouch.ObjCRuntime.Messaging.IntPtr_objc_msgSend (this.Handle, selDelegate));
MarkDirty ();
__mt_WeakDelegate_var = ret;
return ret;
}
[Export ("setDelegate:")]
set {
MonoTouch.ObjCRuntime.Messaging.void_objc_msgSend_IntPtr (this.Handle, selSetDelegate_, value == null ? IntPtr.Zero : value.Handle);
MarkDirty ();
__mt_WeakDelegate_var = value;
}
}
Listing 1 shows the use of IsNewRefcount method (line #8 and #17). It’s the most important since it show that when --newrefcount is enabled we can avoid using backing fields, like __mt_HudView_var (line #1), in several cases. That’s marvellous by itself but with MonoTouch 5.3+ it’s even better.
Why ? because that’s where the linker can shine (and why those changes are made at this stage). Not only it can rewrite the IL to remove the check !IsNewRefcountEnabled () but it can also eliminate the backing field itself, similar to a previous linker optimization (see listing 3). That means you can get types with smaller memory footprints, when using newrefcount (and the linker), since the (unneeded) backing fields won’t be present.
Listing 3: When --new-refcount is enabled
public virtual AtmHudView HudView {
[Export ("__view", ArgumentSemantic.Retain)]
get {
AtmHudView ret;
ret = (AtmHudView) Runtime.GetNSObject (MonoTouch.ObjCRuntime.Messaging.IntPtr_objc_msgSend (this.Handle, sel__view));
return ret;
}
[Export ("set__view:", ArgumentSemantic.Retain)]
set {
if (value == null)
throw new ArgumentNullException ("value");
MonoTouch.ObjCRuntime.Messaging.void_objc_msgSend_IntPtr (this.Handle, selSet__view_, value.Handle);
}
}
Listing 2 shows that a new call, to MakeDirty (line #8 and #15), was also added. However it is only required when the new refcounting is being used (note: the check resides inside the call, not the caller). So the linker can simply remove the call when the normal/default reference counting is used. In such cases the code will simply become:
Listing 4: when --new-refcount is NOT enabled
object __mt_WeakDelegate_var;
public virtual NSObject WeakDelegate {
[Export ("delegate")]
get {
NSObject ret;
ret = (NSObject) Runtime.GetNSObject (MonoTouch.ObjCRuntime.Messaging.IntPtr_objc_msgSend (this.Handle, selDelegate));
__mt_WeakDelegate_var = ret;
return ret;
}
[Export ("setDelegate:")]
set {
MonoTouch.ObjCRuntime.Messaging.void_objc_msgSend_IntPtr (this.Handle, selSetDelegate_, value == null ? IntPtr.Zero : value.Handle);
__mt_WeakDelegate_var = value;
}
}
Nothing dramatic
but this allows, in most cases, the linker to eliminate the use of the new registered_toggleref field inside NSObject, which means every type inheriting from NSObject it will be 4 bytes smaller than before (when you don’t use newrefcount).
This concludes the descriptions of the new linker features for the first alpha release of MonoTouch 5.3. As always testing results and feedback are greatly appreciated.

Pingback: Linker vs Bindings and IsDirectBinding | take a bit, get a byte