iPhone анимация на основе сенсорного - PullRequest
1 голос
/ 07 апреля 2010

Я сейчас работаю над приложением для iPhone и борюсь с анимацией.

Обычно у меня 109 кадров для перемещения человека по экрану, поэтому я слушаю прикосновения и вычисляю, на какие кадры мне нужно переключиться.

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

Какой лучший способ для меня это сделать?

Вот часть исходного кода:

- (void)viewWillAppear:(BOOL)animated {
animationQueue = [[NSMutableArray alloc] initWithObjects:0];
imageArray = [[NSMutableArray alloc] initWithObjects:nil];
for(int i = 1;i<110;i++)
{
    [imageArray addObject:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat: @"%i", i] ofType:@"png"]]];
}
[super viewWillAppear:animated];}

Просмотр загруженного кода:

- (void)viewDidLoad {
animation = [[UIImageView alloc] initWithFrame: CGRectMake(0, 0, 480, 320)];
animation.contentMode = UIViewContentModeCenter;
[self.view addSubview:animation];
animation.image = [imageArray objectAtIndex:40];
[super viewDidLoad];}

Обработчик касаний:

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {  
// Enumerates through all touch objects
for (UITouch *touch in touches) {
    CGPoint touch_point = [touch locationInView:self.view];
    // calculate which frame to end on
    int pos = ceil((touch_point.x/480) * 108);
    [self redrawAnimation:pos];
}}

Перерисовка анимации:

- (void)redrawAnimation:(int)end_frame {
    animation.image = [imageArray objectAtIndex:end_frame];
}

Приложение вылетает, когда вы несколько раз проводите пальцем по экрану.

Ответы [ 3 ]

0 голосов
/ 07 апреля 2010

Разве это не проблема с выделением слишком большого количества памяти? 110 изображений могут занять слишком много. Как насчет изменения в:

- (void)redrawAnimation:(int)end_frame {
  animation.image = [imageArray objectAtIndex:end_frame];
}

до:

- (void)redrawAnimation:(int)end_frame {
  animation.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle]
                                     pathForResource:[NSString stringWithFormat: @"%i", end_frame]
                                              ofType:@"png"]]];
}

и не выделяйте изображения в - (void) viewWillAppear: (BOOL) анимированный.

Я знаю, это было бы намного медленнее, но если бы это был случай ограничения памяти, у вас, скорее, нет другого выбора. Вы также можете попытаться предварительно выделить только часть последовательности, но, в конце концов, буфер может не работать, если вы анимируете изображения быстрее, чем они будут загружены.

0 голосов
/ 07 апреля 2010

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

UIImage, как правило, довольно умный за кулисами. Например. в вашем viewWillAppear, хотя вы создаете 110 ссылок на изображения, вероятно, файлы не загружаются до тех пор, пока они не понадобятся. Когда вы двигаете пальцем по куче, думаете ли вы, что это то, что нужно для фактического вызова / загрузки всех кадров? Может быть, вы где-то ограничиваетесь на пути к этому? Известно также, что UIImage умно сбрасывает растровые данные в ситуациях с нехваткой памяти, но для вызывающего абонента это черный ящик.

Выясните, где именно происходит сбой приложения. Также рассмотрите возможность запуска инструментов для профилирования использования памяти и еще много чего. Это может быть что-то не связанное с памятью (ошибка где-то еще в вашем коде?). Или попробуйте использовать половину или четверть числа изображений и т. Д., Чтобы увидеть, что происходит.

Если это управление ресурсами, у вас будет более точный контроль, если вы будете либо управлять памятью явно, создавая и выпуская UIImages на лету (или каким-либо способом оконной / пакетной предварительной загрузки), либо проверяя Cocos2D или даже сырой OpenGL для правильных спрайтов / текстур, где контроль над этим материалом гораздо более доступен (за счет гораздо большего количества сантехники).

0 голосов
/ 07 апреля 2010

Может ли быть так, что ваша позиция int иногда имеет значение, для которого нет индекса в массиве?

Я имею в виду следующие строки:

int pos = ceil((touch_point.x/480) * 108);
[self redrawAnimation:pos];

Что такое сообщение об ошибкеотладчик, если приложение вылетает?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...