Tengo una aplicación MonoTouch que tiene un UITabBarController, con cada una de las pestañas siendo un UINavigationController. Algunos de estos envuelven un UIViewController que agrega una UITableView y una UIToolbar, y otros envuelven un DialogViewController.Administración de memoria/recursos usando MonoTouch y MonoTouch.Dialog
No he prestado mucha atención a la gestión de memoria/vista hasta el momento (he estado funcionando principalmente en el simulador), pero cuando comencé a probar en un dispositivo real, he notado algunas fallas debido a condiciones de poca memoria (por ejemplo, la aplicación se termina, y descubrí en mi registro que se llamó a DidReceiveMemoryWarning antes de esto). Otras veces noto pausas prolongadas en la capacidad de respuesta de la aplicación que, supongo, se deben a un ciclo de GC.
Hasta ahora he asumido que cada DialogViewController que introduzco en la pila de navegación limpiará sus vistas y otras cosas que se asignan cuando lo muestre. Pero estoy empezando a darme cuenta de que probablemente no sea tan fácil, y que necesito comenzar a llamar a Dispose() sobre cosas.
¿Existen mejores prácticas sobre cómo gestionar los recursos y la memoria con MonoTouch y MT.D? Específicamente:
- ¿Es necesario llamar a Dispose en un DialogViewController después de que se ha reventado? Si es así, ¿dónde es mejor hacer esto? (ViewDidUnload? DidReceiveMemoryWarning? Destructor?)
- ¿El DVC elimina automáticamente objetos como el RootElement que se le pasa o tengo que preocuparme por esto? ¿Qué hay de UIImage que se carga como parte de la representación de una celda de tabla (por ejemplo, StyledStringElement)?
- ¿Hay lugares en los que deba llamar a GC.Collect() para espaciar mejor las colecciones para no tener un poco de capacidad de respuesta cuando ocurre un GC?
- ¿El recolector de basura generacional ayuda con los problemas de interactividad y es lo suficientemente estable como para usar en una aplicación de producción? (Creo que aún se anuncia como "experimental" en MonoDevelop 3.0.2/MT 4.3.3)
- ¿Qué debo hacer en DidReceiveMemoryWarning para reducir la probabilidad de que iOS filme mi aplicación? Dado que cada controlador de vista no visible parece recibir esta llamada, supongo que debería limpiar los recursos del controlador de vista ... ¿debería hacer el mismo tipo de cosas que hago en ViewDidUnload?
- Parece que no me llama mi ViewDidUnload (incluso después de recibir un DidReceiveMemoryWarning). De hecho, no recuerdo haberlo visto nunca en mi registro. Si iOS siempre llamaba mi ViewDidUnload después de DidReceiveMemoryWarning, podía hacer toda la limpieza en ViewDidUnload ... ¿Cuál es la mejor manera de dividir la responsabilidad de limpieza entre ViewDidUnload y DidReceiveMemoryWarning?
Me disculpo por la naturaleza general de esta pregunta - esto parece un buen tema para un libro blanco, pero no pude encontrar ninguna ...
actualización: hacer la pregunta más concreta : después de usar Instruments y el generador de perfiles Xamarin Heapshot, me queda claro que estoy filtrando UIViewControllers cuando el usuario saca la pila de navegación. Rolf archivó bug para esto y tiene dos dups, por lo que este es un problema real para algo más que para mí. Lamentablemente, no he encontrado una buena solución para los UIViewControllers filtrados: no he encontrado un buen lugar para llamar a Dispose() sobre ellos. El lugar natural para liberar recursos asignados por ViewDidLoad se encuentra en el mensaje ViewDidUnload, pero nunca se llama en el simulador, por lo que mi huella de memoria sigue creciendo.En el dispositivo, veo DidReceiveMemoryWarning, pero soy reacio a usar esto como el lugar para liberar mi viewcontroller y sus recursos, ya que no estoy seguro de que iOS realmente descargue mi vista, y por lo tanto no estoy seguro de que mi ViewDidLoad vuelva a ser llamado cualquiera de los dos (lo que lleva a un ViewDidAppear que necesitaría un código defensivo frente a las situaciones en las que se eliminaron sus recursos subyacentes). Me gustaría obtener algunos consejos sobre cómo salir de este lío ...
Esa es una gran cantidad de información valiosa, gracias por poner todo junto. Solo una nota para lectores futuros: desde iOS 6, el sistema no llamará a 'ViewDidUnload'. –