Утечка памяти UIView.BackgroundColor, если используется изображение?

Преамбула: представление контроллера представления, о котором я говорю, используется в UISplitViewController в качестве представления сведений. Он заменяется, если пользователь перемещается с помощью UINavigationController разделенного представления. При нажатии «Назад» создается новый экземпляр моего проблемного контроллера представления, который назначается массиву контроллеров разделенного представления. Каждый раз, когда появляется мое представление, я вижу блок размером 8 МБ, выделенный в инструментах. Навигация вперед и назад в конечном итоге приведет к сбою приложения.

В деталях:

В моем классе, переопределяющем UIViewController, у меня есть:

private UIColor oBgColor = null;

в ViewDidLoad():

    this.oBgColor = UIColor.FromPatternImage ( UIImage.FromFile ( "Data/Images/background.jpg" ) );
// This line here causes memory to go up by 8MB!
    this.View.BackgroundColor = this.oBgColor;

в ViewDidDisappear():

// These lines should sucessfully get rid of the allocated 8MB chunk.    
this.View.BackgroundColor = UIColor.Clear;
    this.oBgColor.Dispose();
    this.View.Dispose();

Код достигает ViewDidDisappear(), как и ожидалось, представление исчезло.

Блок размером 8 МБ выделяется ТОЛЬКО в том случае, если я назначаю this.oBgColor фоновому цвету представления. Оставьте эту строку, и все работает (но у меня нет фона). Каждый раз, когда отображается представление, я вижу, что еще 8 МБ тратятся впустую.

Что тут происходит? Известно ли, что BackgroundImage имеет утечку?

Интересное примечание: если я добавлю UIImageView в качестве подпредставления и использую его изображение вместо назначения свойству BackgroundColor представления, память практически не увеличится и будет правильно освобождена.


person Krumelur    schedule 12.02.2011    source источник


Ответы (1)


Я написал образец на основе вашего кода, и хотя использование памяти увеличивается при ее назначении, утечки нет (я включал и выключал изображение 100 раз, и память не изменилась).

Причина, по которой он поднимается, заключается в том, что свойство BackgroundImage поддерживается копией @property в Objective-C, что означает, что весь объект копируется при назначении, поэтому, если у вас есть огромное изображение шаблона, а затем присвоить его, вы будете для короткий период иметь 2 копии образа в памяти.

Причина, по которой вы видите увеличение памяти, заключается в том, что, как я объяснил вам в IRC, MonoTouch не имеет сжимающего GC в версии 3.

person Geoff Norton    schedule 15.02.2011
comment
Я понимаю. Но это не объясняет, почему мое приложение в конечном итоге будет убито. Вы пытались установить представление с фоновым изображением как (например) представление сведений в контроллере разделенного представления? Тогда это будет именно мой сценарий: нажмите кнопку, и UIViewController oImageController = new ImageControllerWithAViewHavingABgImage(); SplitViewController.ViewControllers = новый UIViewController[] { SplitViewControll.ViewControllers[0], oImageController} - person Krumelur; 15.02.2011
comment
У меня также может быть общая проблема здесь, в моей среде разработки. Я даже сделал новое тестовое приложение сейчас без ничего особенного. Просто окно, без видов. Я использую StringReader для чтения большого файла построчно. В 9 из 10 раз все нормально. Затем, запуская приложение снова, память подскакивает до 160 МБ, и приложение умирает. Я понятия не имею, что происходит. Хотел бы я, чтобы здесь был кто-то из команды MT, чтобы разобраться с проблемами и решить их раз и навсегда... в проекте нет прогресса из-за этих проблем. - person Krumelur; 15.02.2011
comment
Пожалуйста, опубликуйте автономный тестовый пример для проблемы с изображением. - person miguel.de.icaza; 22.02.2011