Nuevo sistema de recuento de referencias en Xamarin.iOS
Xamarin.iOS 9.2.1 introdujo el sistema de recuento de referencias mejorado para todas las aplicaciones de forma predeterminada. Se puede usar para eliminar muchos problemas de memoria que eran difíciles de realizar y corregir en versiones anteriores de Xamarin.iOS.
Habilitación del nuevo sistema de recuento de referencias
A partir de Xamarin 9.2.1, el nuevo sistema de recuento de referencias está habilitado para todas las aplicaciones de forma predeterminada.
Si está desarrollando una aplicación existente, puede comprobar el archivo .csproj para asegurarse de que todas las apariciones de se establecen en , como se muestra MtouchUseRefCountingtrue a continuación:
<MtouchUseRefCounting>true</MtouchUseRefCounting>
Si se establece en false la aplicación, no se usarán las nuevas herramientas.
Uso de versiones anteriores de Xamarin
Xamarin.iOS 7.2.1 y versiones posteriores ofrece una versión preliminar mejorada de nuestro nuevo sistema de recuento de referencias.
Classic API:
Para habilitar este nuevo sistema de recuento de referencias, active la casilla Usar la extensión de recuento de referencias que se encuentra en la pestaña Avanzadas de las opciones de compilación de iOSdel proyecto, como se muestra a continuación:
Tenga en cuenta que estas opciones se han quitado en versiones más recientes de Visual Studio para Mac.
La nueva extensión de recuento de referencias es necesaria para el Unified API y debe habilitarse de forma predeterminada. Es posible que las versiones anteriores del IDE no tengan este valor activado automáticamente y es posible que tenga que realizar una comprobación usted mismo.
Importante
Una versión anterior de esta característica ha estado disponible desde MonoTouch 5.2, pero solo estaba disponible para sgen como versión preliminar experimental. Esta nueva versión mejorada ahora también está disponible para el recolector de elementos no utilizados Denómm.
Históricamente, ha habido dos tipos de objetos administrados por Xamarin.iOS: los que eran simplemente un contenedor alrededor de un objeto nativo (objetos del mismo nivel) y los que ampliaban o incorporaban nuevas funcionalidades (objetos derivados), normalmente manteniendo un estado adicional en memoria. Anteriormente era posible que se pudiera aumentar un objeto del mismo nivel con el estado (por ejemplo, agregando un controlador de eventos de C#), pero que se dejara que el objeto no se rereferenciase y, a continuación, se recopilara. Esto podría provocar un bloqueo más adelante (por ejemplo, si el tiempo de Objective-C ejecución llamó de nuevo al objeto administrado).
El nuevo sistema actualiza automáticamente los objetos del mismo nivel en objetos administrados por el tiempo de ejecución cuando almacenan información adicional.
Esto resuelve varios bloqueos que se han producido en situaciones como esta:
class MyTableSource : UITableViewSource {
public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath) {
var cell = tableView.DequeueReusableCell ("myId");
if (cell != null)
return cell;
cell = new UITableViewCell (UITableViewCellStyle.Default, "myId");
var txt = new UITextField ();
txt.TouchDown += delegate { Console.WriteLine ("...."); };
cell.ContentView.AddSubview (txt);
return cell;
}
}
Sin la extensión de recuento de referencias, este código se bloquearía porque se puede recopilar y, por tanto, su delegado, lo que se traducirá cellTouchDown en un puntero desenlazándose.
La extensión de recuento de referencias garantiza que el objeto administrado permanece activo e impide su colección, siempre que el código nativo conserve el objeto nativo.
El nuevo sistema también elimina la necesidad de la mayoría de los campos de respaldo privados que se usan en los enlaces, que es el enfoque predeterminado para mantener la instancia con vida. El vinculador administrado es lo suficientemente inteligente como para quitar todos esos campos innecesarios de las aplicaciones mediante la nueva extensión de recuento de referencias.
Esto significa que cada instancia de objeto administrado consume menos memoria que antes. También resuelve un problema relacionado en el que algunos campos de respaldo contenían referencias que el tiempo de ejecución ya no necesitaba, lo que hacía que fuera difícil reclamar Objective-C algo de memoria.
