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

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

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

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

04.08.2012, 19:32. Просмотров 3990. Ответов 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.

а затем после еще нескольких нажатий приложение вылетает. Понимаю, что где-то идет утечка памяти, но не знаю где? И как это устранить?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.08.2012, 19:32
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Утечка памяти - Received memory warning? (Программирование iOS):

Есть ли здесь утечка памяти? - Программирование iOS
Вот код: -(NSString *)getCookie { NSMutableURLRequest *cookieRequest = ]; ; NSHTTPURLResponse *response = nil;...

Thread 1: Program received signal "SIGABRT" - Objective-C
Добрый вечер. Использую Кокос2Д. Мне надо чтобы спрайт генерировался каждые 2 секунды с позиции другого спрайта(арроу): Пытался...

HttpWebRequest, расход памяти непомерно больших объемов и , как следствие, утечка памяти - C#
Добрый вечер. Мне была поставлена такая задача. Написать приложение, которая загружает из списка ссылки с сайта и ищет там определенную...

Вектор, утечка памяти, функция создания и выделение памяти - C (СИ)
Здравствуйте. Есть проблема. функция malloc выделяет память лишь в функции CreateVector(), и при выходе из нее указатель теряется. Или не...

Утечка памяти - C++
Не могу понять как избежать утечки памяти в своей программе... привожу кусок в одном из мест где на мой взгляд она происходит... Array...

Утечка памяти - Free Pascal
Программа написана в Lazarus 1.6 и активно работате с sqlite3. В программе 2 потока. При работе программы в диспетчере задач объем...

8
zulkis
682 / 609 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
04.08.2012, 20:16 #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;
?
0
envoy2000
0 / 0 / 0
Регистрация: 29.07.2012
Сообщений: 7
04.08.2012, 20:36  [ТС] #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 (прочитал где-то что так можно, наверное это неправильно)
0
zulkis
682 / 609 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
04.08.2012, 20:44 #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), в котором эти проперти есть?
0
envoy2000
0 / 0 / 0
Регистрация: 29.07.2012
Сообщений: 7
04.08.2012, 21:16  [ТС] #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 штук) не создавая новых объектов?
0
zulkis
682 / 609 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
04.08.2012, 21:41 #6
Что такое "слой" в Вашей терминологии?

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


Оо, а почитайте-ка документацию.
Objective-C
1
@property (nonatomic, retain) UIImage *image;
Ни о чем не говорит?
Слой - subview. Да, хорошо, почитаю. Спасибо за помощь.
0
zulkis
682 / 609 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
04.08.2012, 22:39 #8
Цитата Сообщение от envoy2000 Посмотреть сообщение
Слой - subview.
Ну тогда у вас каждый "слой" - 1 imageView.
И у Вас всегда 7 картинок.
Давайте так - Что именно Вам нужно сделать? Так быстрее разберемся.
0
envoy2000
0 / 0 / 0
Регистрация: 29.07.2012
Сообщений: 7
05.08.2012, 14:02  [ТС] #9
Цитата Сообщение от zulkis Посмотреть сообщение
Ну тогда у вас каждый "слой" - 1 imageView.
И у Вас всегда 7 картинок.
Давайте так - Что именно Вам нужно сделать? Так быстрее разберемся.
Да всегда 7 картинок выводимых в замкнутом "кольце" и подмена их на новые в следующем "кольце". У меня есть большое количество картинок 320х360 (сколько не пока не знаю, их количество может меняться (от 300 до 5000 штук)), мне нужно скролить их последовательно по одной на экране. Когда скрол дойдет до последней картинки , опять видим первую (бесконечное кольцо получается).

Добавлено через 14 часов 28 минут
Всем спасибо за помощь.
Проблема решена. Приложение падало из-за метода imageNamed - так как он кэширует каждую картинку , что и приводило к расходу памяти. Решение: использовать вместо imageNamed - метод imageWithContentsOfFile, который не кэширует изображения.
0
05.08.2012, 14:02
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.08.2012, 14:02
Привет! Вот еще темы с ответами:

Утечка памяти - Delphi
Доброго времени суток! Подскажите, пожалуйста: Нужно залить много мелких файлов (до 1 Мб). Файлы создаются динамически - своеобразный...

Утечка памяти в - C++
Кто подскажет плиз. Тут у меня утечка памяти foreach (var file in xpsFiles) { ...

Утечка памяти? - C++
В Лафоре такой код: #include &lt;iostream&gt; using namespace std; /////////////////////////////////////////////////////////// class...

Утечка памяти - C++
Где я допустил ее(утечку)? #define _CRT_SECURE_NO_WARNINGS #include &lt;iostream&gt; #include &lt;cstring&gt; #include &lt;string&gt; class...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

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