Форум программистов, компьютерный форум CyberForum.ru

Программирование iOS/iPhone

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 31, средняя оценка - 4.65
envoy2000
0 / 0 / 0
Регистрация: 29.07.2012
Сообщений: 7
#1

Утечка памяти - Received memory warning? - Программирование iOS/iPhone

04.08.2012, 19:32. Просмотров 3854. Ответов 8
Метки нет (Все метки)

Всем привет!
Подскажите как можно решить проблему и где я делаю ошибки?

Использую ScrollView, при начальной загрузке приложения в методе viewDidLoad в цикле
заполняю суб-слои ScrollView картинками при помощи метода addSubview:imageView: (код ниже)
(в результате можно скролить полосу из 7 картинок)


//*********************************************************************
- (void)addImageWithName: (NSString*)imageString atPosition: (int)position {

// add image to scroll view
UIImage *image = [UIImage imageNamed:imageString];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = CGRectMake(position*320, 0, 320, 360);
[scrollView1 addSubview:imageView];

self.image = nil;
self.imageView = nil;

}
//*********************************************************************


Затем при нажатии на кнопку реализую замену созданных суб-слоев другими картинками:

//*********************************************************************
- (void)insertImageWithName: (NSString*)imageString atPosition: (int)position {

//===========================================================
NSArray *subviews = [scrollView1 subviews];
[ [ subviews objectAtIndex: position ] removeFromSuperview];
//===========================================================

// add image to scroll view
UIImage *image = [UIImage imageNamed:imageString];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = CGRectMake(position*320, 0, 320, 360);
[scrollView1 insertSubview:imageView atIndex: position];

self.image = nil;
self.imageView = nil;
//*********************************************************************

-(IBAction) InsertPicture
{
for (int i = 0; i < 7; i++) {
[self insertImageWithName:[NSString stringWithFormat:@"%i.png",z] atPosition:i];
NSLog(@"%i.png // слой= i = %i",z,i);
z=z+1;
}


При нажатии на кнопку все работает хорошо метод insertSubview: atIndex: работает , но на реальном
девайсе (в симуляторе все работает без проблем) после 10-15 нажатий (смен блоков из 7 картинок) xcode выдает сообщение:


Received memory warning.

а затем после еще нескольких нажатий приложение вылетает. Понимаю, что где-то идет утечка памяти, но не знаю где? И как это устранить?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
zulkis
681 / 608 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
04.08.2012, 20:16     Утечка памяти - Received memory warning? #2
Во-первых метода (addSubview:imageView - у Вас нет, ну это вероятно ошибка была допущена со вторым двоеточием. Ну да ладно.
Во-вторых, если вы 1 раз добавили кучку ImageView, при следующем "добавлении", а правильнее будет сказать "отображении" новых изображении, Вам нужно не добавлять заного новые UIImageView, а только подставить новые картинки в них.

Ваша ошибка в том, что вы даже не релизите предыдущие UIImageView, ясное дело память кончается - система убивает приложение.
Так вот - самый простой вариант - пробегать по всем -(NSArray*)subviews у UIScrollView, и подменять картинки.
Самый безболезненный вариант:
1. Выставляете contentSize на размер всех Ваших картинок.
2. Отрисовываете столько UIImageView на UIScrollView, сколько может уместиться их в его bounds.size;
Затем, при вызове -(void)scrollViewDidScroll; - вы должны подсчитать индексы для картинок в зоне видимости и засетить в лежащие на scrollView imageView Ваши картинки, подставив соответствующий фрейм для каждого UIImageView.
Но это более сложный, так сказать, вариант.

Опять же - ответ на Ваш вопрос - Вы не очищаете subviews scrollView (очищаете, но реально retain count > 0 получается все равно) перед повторным наложением новых imageView.
А точнее - Я лично не вижу вызова [imageView release]; - вообще нигде. После его alloc]init] в локальный указатель.
И что это такое:
C
1
2
self.image = nil;
self.imageView = nil;
?
envoy2000
0 / 0 / 0
Регистрация: 29.07.2012
Сообщений: 7
04.08.2012, 20:36  [ТС]     Утечка памяти - Received memory warning? #3
Цитата Сообщение от zulkis Посмотреть сообщение
Во-первых метода (addSubview:imageView - у Вас нет, ну это вероятно ошибка была допущена со вторым двоеточием. Ну да ладно.
Во-вторых, если вы 1 раз добавили кучку ImageView, при следующем "добавлении", а правильнее будет сказать "отображении" новых изображении, Вам нужно не добавлять заного новые UIImageView, а только подставить новые картинки в них.

Ваша ошибка в том, что вы даже не релизите предыдущие UIImageView, ясное дело память кончается - система убивает приложение.
Так вот - самый простой вариант - пробегать по всем -(NSArray*)subviews у UIScrollView, и подменять картинки.
Самый безболезненный вариант:
1. Выставляете contentSize на размер всех Ваших картинок.
2. Отрисовываете столько UIImageView на UIScrollView, сколько может уместиться их в его bounds.size;
Затем, при вызове -(void)scrollViewDidScroll; - вы должны подсчитать индексы для картинок в зоне видимости и засетить в лежащие на scrollView imageView Ваши картинки, подставив соответствующий фрейм для каждого UIImageView.
Но это более сложный, так сказать, вариант.

Опять же - ответ на Ваш вопрос - Вы не очищаете subviews scrollView (очищаете, но реально retain count > 0 получается все равно) перед повторным наложением новых imageView.
А точнее - Я лично не вижу вызова [imageView release]; - вообще нигде. После его alloc]init] в локальный указатель.
И что это такое:
C
1
2
self.image = nil;
self.imageView = nil;
?
Спасибо за ответ!
Я использую в проекте Automatic Reference Counting , поэтому и нет [release], хотя пробовал и без ARC все-равно также вылетало. СontentSize на размер всех картинок выставить не могу, т.к картинок очень много, получиться очень длинная полоса с картинками, большого размера (пробовал уже, приложение вылетает при начальной загрузке). "Так вот - самый простой вариант - пробегать по всем -(NSArray*)subviews у UIScrollView, и подменять картинки." - так я вроде так и делаю используя в цикле метод [scrollView1 insertSubview:imageView atIndex: position];, предварительно удалив старый слой:
NSArray *subviews = [scrollView1 subviews];
[ [ subviews objectAtIndex: position ] removeFromSuperview];
"И что это такое:
C
1
2
self.image = nil;
self.imageView = nil;
?[/QUOTE]" - это обнуление текущих объектов image и imageViev (прочитал где-то что так можно, наверное это неправильно)
zulkis
681 / 608 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
04.08.2012, 20:44     Утечка памяти - Received memory warning? #4
СontentSize на размер всех картинок выставить не могу, т.к картинок очень много, получиться очень длинная полоса с картинками, большого размера (пробовал уже, приложение вылетает при начальной загрузке)
- Чушь. Значит у Вас еще где то косяки, причем серьезные. И картинок у Вас не много, у Вас их 7
Попробуйте не
Objective-C
1
2
3
4
//===========================================================
NSArray *subviews = [scrollView1 subviews];
[ [ subviews objectAtIndex: position ] removeFromSuperview];
//===========================================================
а непосредственно вызвав метод перед подгрузкой новых картинок:
Objective-C
1
2
3
for (UIView *view in [scrollView subviews]) {
   [view removeFromSuperview];
}
Тогда у Вас будет совершенно чистый scrollView. Если снова будет падать - просмотрите retainCount у этих самых UIImageView в разных местах. Где то должна быть ошибка. Так проще выяснить где.
Цитата Сообщение от envoy2000 Посмотреть сообщение
текущих объектов image и imageViev
Что значит текущих? Класс у Вас какой(self), в котором эти проперти есть?
envoy2000
0 / 0 / 0
Регистрация: 29.07.2012
Сообщений: 7
04.08.2012, 21:16  [ТС]     Утечка памяти - Received memory warning? #5
Цитата Сообщение от zulkis Посмотреть сообщение
- Чушь. Значит у Вас еще где то косяки, причем серьезные. И картинок у Вас не много, у Вас их 7
Попробуйте не
Objective-C
1
2
3
4
//===========================================================
NSArray *subviews = [scrollView1 subviews];
[ [ subviews objectAtIndex: position ] removeFromSuperview];
//===========================================================
а непосредственно вызвав метод перед подгрузкой новых картинок:
Objective-C
1
2
3
for (UIView *view in [scrollView subviews]) {
   [view removeFromSuperview];
}
Тогда у Вас будет совершенно чистый scrollView. Если снова будет падать - просмотрите retainCount у этих самых UIImageView в разных местах. Где то должна быть ошибка. Так проще выяснить где.

Что значит текущих? Класс у Вас какой(self), в котором эти проперти есть?
Картинок у меня не 7, я использую блоки по 7 картинок (всего картинок может быть сколько угодно).
Эта же конструкция полностью удалит все суб-слои scrollview и я не смогу использовать [scrollView1 insertSubview:imageView atIndex: position]; для вставки нового слоя вместо старого (может я ошибаюсь конечно). Может причина в том что я постоянно создаю новые объекты в коде UIImageView *imageView = [[UIImageView alloc] initWithImage:image] при вставке insert изображений; и они и есть причина падения приложения? А как можно запихать новую картинку в старый объект UIImageView (их при загрузке приложения создается 7 штук) не создавая новых объектов?
zulkis
681 / 608 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
04.08.2012, 21:41     Утечка памяти - Received memory warning? #6
Что такое "слой" в Вашей терминологии?

Цитата Сообщение от envoy2000 Посмотреть сообщение
А как можно запихать новую картинку в старый объект UIImageView (их при загрузке приложения создается 7 штук) не создавая новых объектов?
Оо, а почитайте-ка документацию.
Objective-C
1
@property (nonatomic, retain) UIImage *image;
Ни о чем не говорит?
envoy2000
0 / 0 / 0
Регистрация: 29.07.2012
Сообщений: 7
04.08.2012, 22:33  [ТС]     Утечка памяти - Received memory warning? #7
Цитата Сообщение от zulkis Посмотреть сообщение
Что такое "слой" в Вашей терминологии?


Оо, а почитайте-ка документацию.
Objective-C
1
@property (nonatomic, retain) UIImage *image;
Ни о чем не говорит?
Слой - subview. Да, хорошо, почитаю. Спасибо за помощь.
zulkis
681 / 608 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
04.08.2012, 22:39     Утечка памяти - Received memory warning? #8
Цитата Сообщение от envoy2000 Посмотреть сообщение
Слой - subview.
Ну тогда у вас каждый "слой" - 1 imageView.
И у Вас всегда 7 картинок.
Давайте так - Что именно Вам нужно сделать? Так быстрее разберемся.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.08.2012, 14:02     Утечка памяти - Received memory warning?
Еще ссылки по теме:

Приложение вылетает, сообщая о нехватке памяти Objective-C
Swift Представление изображения в памяти. Как?
Получить объект по адресу в памяти Objective-C
Objective-C HTMLParser - ошибка памяти
Objective-C Воспроизведение аудио из памяти используя AVAydioPlayer

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
envoy2000
0 / 0 / 0
Регистрация: 29.07.2012
Сообщений: 7
05.08.2012, 14:02  [ТС]     Утечка памяти - Received memory warning? #9
Цитата Сообщение от zulkis Посмотреть сообщение
Ну тогда у вас каждый "слой" - 1 imageView.
И у Вас всегда 7 картинок.
Давайте так - Что именно Вам нужно сделать? Так быстрее разберемся.
Да всегда 7 картинок выводимых в замкнутом "кольце" и подмена их на новые в следующем "кольце". У меня есть большое количество картинок 320х360 (сколько не пока не знаю, их количество может меняться (от 300 до 5000 штук)), мне нужно скролить их последовательно по одной на экране. Когда скрол дойдет до последней картинки , опять видим первую (бесконечное кольцо получается).

Добавлено через 14 часов 28 минут
Всем спасибо за помощь.
Проблема решена. Приложение падало из-за метода imageNamed - так как он кэширует каждую картинку , что и приводило к расходу памяти. Решение: использовать вместо imageNamed - метод imageWithContentsOfFile, который не кэширует изображения.
Yandex
Объявления
05.08.2012, 14:02     Утечка памяти - Received memory warning?
Ответ Создать тему
Опции темы

Текущее время: 09:10. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru