iPhone SDK: 3.0 очищает кэш изображения? Потому что 2.2.1 нет! - PullRequest
1 голос
/ 20 июня 2009

Я создаю приложение для iPhone, которое включает в себя более одной кнопки, которые все анимируют один и тот же UIImageView. Он хорошо работает в симуляторе (как и практически во всех приложениях), но когда дело доходит до устройства, он хорошо воспроизводит анимацию, но при повторном нажатии кнопок приложение закрывается. Пока что я реализовал 2 кнопки. Вот что происходит, когда они нажаты. Хорошо, у меня есть 44 МБ оперативной памяти, когда мое приложение запускается. Затем, когда я нажимаю первую из 2 кнопок, запускающих анимацию, доступная память уменьшается до 31 и поднимается до 32, затем, когда я нажимаю вторую кнопку, доступная память понижается до 9, затем поднимается до 24, а затем странным образом снижается до 10 медленно. Если затем нажать первую кнопку, то доступная память увеличивается до 14 МБ. При повторном нажатии этих кнопок память приложений уменьшается до 4–3 МБ и выходит. В приборах нет утечек. Вот мой код, если кто-то может определить, где скрывается проблема с памятью. (Кстати, я все еще работаю на 2.2.1, потому что, если я обновлюсь до 3.0, я не смогу тестировать свои приложения на устройстве, так как я еще не зарегистрирован в программе для разработчиков Apple, и я следовал онлайн-учебнику, чтобы получить приложения на устройство, которое работает только с 2.2.1)

 @synthesize 123pig;
    - (IBAction)startClick:(id)sender{
    animationTimer = [NSTimer scheduledTimerWithTimeInterval:(1.00/30.00) target:self selector:@selector(tick) userInfo:nil repeats:NO];

        123pig.animationImages = [NSArray arrayWithObjects:
                                [UIImage imageNamed: @"123pigapple0001.png"],
                                 [UIImage imageNamed: @"123pigapple0002.png"],
                                 [UIImage imageNamed: @"123pigapple0003.png"],
                                 [UIImage imageNamed: @"123pigapple0004.png"],
                                  [UIImage imageNamed: @"123pigapple0005.png"],
                                  [UIImage imageNamed: @"123pigapple0006.png"],
                                  [UIImage imageNamed: @"123pigapple0007.png"],
                                  [UIImage imageNamed: @"123pigapple0008.png"],
                                  [UIImage imageNamed: @"123pigapple0009.png"],
                                  [UIImage imageNamed: @"123pigapple0010.png"],
                                  [UIImage imageNamed: @"123pigapple0011.png"],
                                  [UIImage imageNamed: @"123pigapple0013.png"],
                                  [UIImage imageNamed: @"123pigapple0014.png"],
                                  [UIImage imageNamed: @"123pigapple0015.png"],
                                  [UIImage imageNamed: @"123pigapple0016.png"],
                                  [UIImage imageNamed: @"123pigapple0017.png"],
                                  [UIImage imageNamed: @"123pigapple0018.png"],
                                  [UIImage imageNamed: @"123pigapple0019.png"],
                                  [UIImage imageNamed: @"123pigapple0020.png"],nil];

        [123pig setAnimationRepeatCount:1];
        123pig.animationDuration =.7;
        [123pig startAnimating];
}

    - (void)tick{
    [self animatePig];
}

    - (void)animatePig{

    UIImage *pigImage13=[UIImage imageNamed:@"123pigapple0020.png"];


    if(123pig.image == pigImage13)
        123pig.image = pigImage13;
    else
        123pig.image = pigImage13;






    }
    - (IBAction)startClick1:(id)sender{
    animationTimer1 = [NSTimer scheduledTimerWithTimeInterval:(1.00/30.00) target:self selector:@selector(tick1) userInfo:nil repeats:NO];
        123pig.animationImages = [NSArray arrayWithObjects:
                              [UIImage imageNamed: @"123pig0015.png"],
                              [UIImage imageNamed: @"123pig0016.png"],
                              [UIImage imageNamed: @"123pig0017.png"],
                              [UIImage imageNamed: @"123pig0018.png"],
                              [UIImage imageNamed: @"123pig0019.png"],
                              [UIImage imageNamed: @"123pig0020.png"],
                              [UIImage imageNamed: @"123pig0021.png"],
                              [UIImage imageNamed: @"123pig0022.png"],
                              [UIImage imageNamed: @"123pig0023.png"],
                              [UIImage imageNamed: @"123pig0024.png"],
                              [UIImage imageNamed: @"123pig0025.png"],
                              [UIImage imageNamed: @"123pig0026.png"],
                              [UIImage imageNamed: @"123pig0027.png"],
                              [UIImage imageNamed: @"123pig0028.png"],
                              [UIImage imageNamed: @"123pig0029.png"],
                              [UIImage imageNamed: @"123pig0030.png"],
                              [UIImage imageNamed: @"123pig0031.png"],
                              [UIImage imageNamed: @"123pig0032.png"],
                              [UIImage imageNamed: @"123pig0033.png"],
                              [UIImage imageNamed: @"123pig0034.png"],
                              [UIImage imageNamed: @"123pig0035.png"],
                              [UIImage imageNamed: @"123pig0036.png"],
                              [UIImage imageNamed: @"123pig0037.png"],
                              [UIImage imageNamed: @"123pig0038.png"],
                              [UIImage imageNamed: @"123pig0039.png"],
                              [UIImage imageNamed: @"123pig0040.png"],
                              [UIImage imageNamed: @"123pig0041.png"],
                              [UIImage imageNamed: @"123pig0042.png"],
                              [UIImage imageNamed: @"123pig0043.png"],
                              [UIImage imageNamed: @"123pig0044.png"],
                              [UIImage imageNamed: @"123pig0045.png"],
                              [UIImage imageNamed: @"123pig0046.png"],
                              [UIImage imageNamed: @"123pig0047.png"],
                              [UIImage imageNamed: @"123pig0048.png"],

                              nil];

    [123pig setAnimationRepeatCount:1];
    123pig.animationDuration =2.7;
    [123pig startAnimating];


      }
    - (void)tick1{
        [self animatePig1];
    }

    - (void) animatePig1{

        UIImage *pigImage11=[UIImage imageNamed:@"123pig0048.png"];


        if(123pig.image == pigImage11)
            123pig.image = pigImage11;
        else
            123pig.image = pigImage11;






    }
    - (void)stopTimer
    {
    [animationTimer invalidate];
    [animationTimer release];
    [animationTimer1 invalidate];
    [animationTimer1 release];
    }







    -(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [[event allTouches] anyObject];
    CGPoint location = [touch locationInView:touch.view];
    123pig.center = location; 
    }

    - (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    }



    - (void)dealloc {
    [super dealloc];
    [123pig release];
    }
@end

У меня есть идея, что это вызвало его imageNamed, и что 2.2.1 не очищает его кеш даже после предупреждения о памяти, и на другой вопрос SO кто-то сказал: «Я понимаю, что кэш + imageNamed: должен уважать память предупреждения на iPhone OS 3.0. Протестируйте его, когда у вас будет возможность, и сообщите об ошибках, если обнаружите, что это не так ». Теперь, даже если бы я загрузил прошивку и SDK 3.0, я бы не знал, очищал ли он кэш imageNamed, потому что не смог бы протестировать его на устройстве! Кстати, отвечая, имейте в виду, что я новичок в iPhone SDK. Заранее спасибо.

---------------- Изменить ---------------- Меня только что приняли в программу для разработчиков Apple iphone. WOOOHOOO, я проверю, правильно ли 3.0 выпускает кэшированные изображения.

------------- Редактировать ------------------ Да, он выпускает кэшированные изображения. Проверьте мой ответ ниже для дальнейшего разъяснения.

Ответы [ 3 ]

1 голос
/ 21 июня 2009

Ладно, люди. Казалось бы, iPhone OS 3.0 очищает кэшированные изображения с помощью команды предупреждения о получении памяти, wooohooo! Me 1, Xcode 0. Немного подробнее: в iPhone OS 2.2.1, когда вы выпускаете анимированный просмотр изображений, кэшированные изображения не выпускаются, поэтому, если в вашем приложении было множество анимаций, то в конечном итоге iPhone исчерпал бы память и выйти. Таким образом, вам просто нужно пойти на другие более сложные методы анимации, и никто не хочет делать это, если они могут избежать этого. Но теперь освобождение очищает кеш! Я могу сказать, потому что, когда я нажимаю кнопку в моем приложении, чтобы анимировать представление, есть некоторое ожидание, пока анимация не будет воспроизведена, тогда, если она нажата снова, нет ожидания (потому что она кеширует это) что оживляет это представление, предыдущая кэшированная анимация выпущена! Итак, нажатие первой кнопки дает вам первоначальное ожидание, поэтому я могу расслабиться и приступить к разработке, а не пытаться исправить проблему управления памятью, которая сводится к ошибке яблок.

0 голосов
/ 21 июня 2009

Ваш код деаллока неверный. Вы должны только выпустить 123pig, а не освобождать его. Вы должны сделать это перед вызовом [super dealloc], поскольку после этого вызова все переменные вашего экземпляра (включая 123pig) могут быть признаны недействительными. Возможно, это проявилось как не освобождение памяти изображения, так как имеется свисающая ссылка на 123pig.

0 голосов
/ 21 июня 2009

Я действительно запутался в поведении ваших таймеров. Вы запускаете анимацию pig UIImageView, а затем через 1/30-ю секунду ваш таймер срабатывает и устанавливает изображение свиньи на что-то еще?

Возможно, вы захотите объединить эти два метода анимации (UIImageView animationImages и ручная анимация с использованием таймера). UIImageView действительно не предназначен для воспроизведения длинных анимаций (см. этот вопрос ). Я думаю, что он запускает все изображения сразу, когда вы запускаете анимацию - таким образом, огромный удар памяти.

Лучше было бы использовать таймер для всего и сохранить локальную переменную, соответствующую текущему кадру. Когда ваш таймер срабатывает, вы можете загрузить только одно изображение, используя imageNamed: и применить его к UIImageView. Я не уверен, что такое кэширование UIImage, но я уверен, что сложить 100 из них в UIImageView - плохая идея.

Есть ли шанс, что вы также можете уменьшить частоту кадров вашей анимации? Кажется, вы пытаетесь пролистать все 100 изображений в анимации свиньи за 2,7 секунды - это 37 кадров в секунду! 24 кадра в секунду, вероятно, подойдут и помогут уменьшить объем используемой памяти.

Также - это не по теме, но я заметил, что вы вызываете [123pig dealloc] в своей функции dealloc. В общем, вы должны просто вызвать release, и dealloc будет вызываться автоматически, если счет сохранения объекта равен нулю (то есть объект больше не используется). Вызов его вручную может привести к уничтожению вещей, которые другой объект в приложении все еще использует. Возможно, это не имеет значения в этом случае, но это может вызвать некоторые неприятные ошибки в других сценариях.

Извините, у меня нет четкого ответа на вопрос о кеше. Надеюсь, это немного поможет!

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