В процессе разработки мобильных приложений для iOS с использованием Xamarin Studio и Monotouch(Xamarin.iOS) мы столкнулись со следующей проблемой:
приложение ‘вылетало’ после активного использования по непонятной нам причине. Ошибку было сложно поймать, так как она не фиксировалась в debug mode. Оставалась запись в Crash Device Logs, но она не позволяла выявить причину ошибки.
Начали разбираться и смотреть в сторону утечек памяти. Для мониторинга утечек используемой памяти мы используем утилиту Instruments. Вызов утилиты доступен из Xamarin Studio/Tools/Launch Instruments. Оказалось, что память, используемая приложением, увеличивалась, но не освобождалась в процессе работы мобильного приложения. Поискав решение проблемы в интернете, наткнулись на любопытную рекомендацию от сотрудников Xamarin.
Оказывается, что если в пользовательском интерфейсе используется элемент, который ждет события пользователя, например кнопка UIButoon с событием TouchUpInside , то эта кнопка обязательна должна быть полем или свойством класса экрана(Screen), а не объявляться внутри метода. Рассмотрим пример.
Этот код может привести к утечке памяти и внезапному закрытию приложения:
public override ViewDidLoad() { var button = new UIButton(); button.TouchUpInside += delegate{ //выполнить действие }; View.AddSubview(button); }
Код после выполнения рекомендации сотрудников Xamarin: выносим кнопку в поле класса экрана
UIButton button; public overide ViewDidLoad() { button = new UIButton(); button.TouchUpInside += delegate{ //выполнить действие }; View.AddSubview(button); }
Конечно, это далеко не единственная рекомендация в борьбе с утечками памяти, но после выполнения подобных замен во всем проекте нам удалось резко увеличить стабильность работы приложений.
]]>