Может кто-нибудь указать мне некоторые стратегии для устранения утечек памяти в monotouch? - PullRequest
2 голосов
/ 25 июня 2011

Я почти закончил с моим первым приложением monotouch, почти так, но для некоторых больших проблем с утечками памяти. Несмотря на то, что я переопределяю viewDidUnload на каждом контроллере представления, так что для каждого создаваемого элемента пользовательского интерфейса я сначала удаляю его из его суперпредставления, затем вызываю Dispose и затем устанавливаю его в null, проблема сохраняется. Использование инструментов не помогает, оно не обнаруживает утечки памяти, а распределение памяти не указывает мне на то, что я могу отследить.

Мое приложение использует в основном MPMoviePlayer для воспроизведения видеопотоков, а также отображает галерею изображений из изображений, загруженных через http. Обе операции вызывают проблемы.

Любые идеи будут очень признательны, спасибо.

Ответы [ 2 ]

6 голосов
/ 01 июля 2011

Мастер, конечно, прав.Грасиас Мигель.Однако я хотел дать более подробное объяснение того, что я сделал, в надежде, что это поможет будущим колледжам Ксамарина.

1) MPMoviePlayer хранит видеобуфер, который немного липкий.Я сделал уникальный экземпляр, работающий на AppDelegate, и повторно использовал его в представлениях, которые показывают видео.Поэтому вместо инициализации MPMoviePlayerController с помощью URL-адреса вы используете конструктор без аргументов, а затем устанавливаете свойство ContentUrl и вызываете Play ().

2) Не полагайтесь на вызываемый ViewDidUnload для очистки ваших объектов,потому что это не называется последовательно.Например, я использую много модальных контроллеров представления, и этот метод никогда не вызывался.Память только продолжала накапливаться, пока приложение не рухнуло.Лучше позвоните, чтобы очистить код напрямую.

3) Изображения были самым большим объятием памяти, которое у меня было.Даже изображения внутри UIImageViews, которые просто использовались в качестве фона, никогда не удалялись бы.Мне пришлось специально вызывать следующий код на каждом изображении, прежде чем я смог очистить память:

myImageView.RemoveFromSuperview();
myImageView.Image.Dispose();
myImageView.Image = null;
myImageView.Dispose();
myImageView = null;

4) Остерегайтесь UIWebView, он может обнять много памяти, особенно если есть какой-тоAJAX-взаимодействие выполняется на странице, которую вы загружаете.Вызов следующего кода немного помог, но не решил всех проблем.Остаются некоторые утечки памяти, от которых я не смог избавиться:

NSString keyStr = new NSString("WebKitCacheModelPreferenceKey");
NSUserDefaults.StandardUserDefaults.SetValueForKey(NSObject.FromObject(val), keyStr);

5) Если можете, избегайте использования Interface Builder.В некоторых случаях мне никогда не удавалось выпустить элементы пользовательского интерфейса, созданные в файлах xib.Позиционирование всего вручную может быть затруднительным, но если вы используете приложение, интенсивно использующее память, создание всех ваших контроллеров представления в коде может быть правильным решением.

6) Использование анонимных методов в качестве обработчиков событий - это хорошо, и моя помощьудобочитаемость кода, но в некоторых случаях невозможность вручную отсоединить обработчик событий стала проблемой.Ссылки на нежелательный объект остаются в памяти.

7) В моем UITableViewSource я смог более эффективно обрабатывать память, создавая UIImages, которые я использую для независимой стилизации ячеек, а затем просто повторно используя их на моем GetViewForHeader иМетоды GetCell.

И последнее.даже если инструменты не совсем совместимы с тем, как Monotouch делает что-либо, использование «Memory Monitor» было ценным инструментом, но если у вас возникли проблемы, он действительно может помочь.

Эти стратегии решили большинство моих проблем.Некоторые из них могут быть довольно очевидными в ретроспективе, но я подумал, что не мешало бы передать их.

Счастливого кодирования и да здравствует c # на iPhone

0 голосов
/ 26 июня 2011

Элементы пользовательского интерфейса, скорее всего, не являются ответственными, они почти не используют память.И вызов Dispose () / nulling помогает, но только чуть-чуть.

Более вероятным источником проблемы являются такие объекты, как MPMoviePlayer, загрузка изображений и рендеринг изображений.Возможно, вы сохраняете ссылки на те объекты, которые мешают GC избавиться от них.

...