Почему загрузка изображений размером более мегабайта занимает всю память моего iPhone?

Я пишу приложение, которое должно одновременно хранить в памяти около сорока файлов JPEG размером 44 КБ. Я слышал, что приложения могут использовать около 22 мегабайт, прежде чем выдает предупреждение о нехватке памяти, поэтому я почти уверен, что это должно быть возможно. Однако, как только я передаю загруженный мегабайт, в консоли начинают появляться следующие сообщения:

Mon Jun  8 16:37:19 unknown configd[21] : kernel memory event (90), free: 374, active: 1736, inactive: 959, purgeable: 0, wired: 6260
Mon Jun  8 16:37:20 unknown configd[21] : kernel memory event (95), free: 363, active: 876, inactive: 492, purgeable: 0, wired: 6241
Mon Jun  8 16:37:20 unknown SpringBoard[22] : Memory level is critical (5%). No apps to kill. Will kill SpringBoard
Mon Jun  8 16:37:24 unknown SpringBoard[22] : Jetsaming SpringBoard...

Затем он возвращает меня на главный экран.

Вот код, который я использую для загрузки изображений:

#define NUM_IMAGES 40

@interface MyClass : NSObject {
    UIImageView* imageView;
    UIImage* loadedImages[NUM_IMAGES];
}

- (void)initImages;

@property (nonatomic, retain) IBOutlet UIImageView* imageView;

@end


@implementation MyClass

@synthesize imageView;

- (void)initImages {
    int i;
    for (i = 0; i < NUM_IMAGES; i++) {
        loadedImages[i] = [UIImage imageNamed:[NSString stringWithFormat:IMAGE_FORMAT, i+1]];
    }
    imageView.image = loadedImages[0];
}

@end

Что-то я здесь делаю не так? Могут ли приложения для iPhone действительно использовать только мегабайт памяти?


person Community    schedule 08.06.2009    source источник


Ответы (2)


Когда вы загружаете сжатое изображение, такое как изображение в формате JPEG, оно обычно будет несжатым (поскольку это то, что нужно сделать, чтобы вы могли делать что-то полезное с изображением, например, отображать его или манипулировать им).

Несжатое изображение определенно будет больше, чем 44 КиБ, которые занимает сжатое изображение в формате JPEG (примерно 3 или 4 байта, умноженные на ширину и высоту). Поэтому у вас заканчивается память быстрее, чем вы думаете, просто глядя на размеры JPEG.

Если вам действительно нужно только хранить файлы JPEG в памяти (и ничего не делать с ними, просто удерживая их), вы можете просто сохранить необработанный поток байтов в памяти и загрузить его как изображение только тогда, когда он вам действительно нужен.

Но могут быть и другие альтернативы, в зависимости от того, что вам нужно делать. Вам действительно нужны сразу все изображения в памяти? Можете ли вы отложить загрузку одного изображения до тех пор, пока оно не понадобится (и выгрузить другие в это время) для экономии памяти? Вам нужна только определенная информация из каждого изображения, которую можно кэшировать (и после чего вам больше не понадобится само изображение)? и т.д. ...

person Joey    schedule 08.06.2009
comment
Спасибо за объяснение, помогло. Я заставил его хранить данные JPEG для изображений с полным разрешением в памяти и отображать изображения с четвертью разрешения при изменении или загрузке изображений. Спасибо! - person ; 09.06.2009

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

См. Ответ на вопрос SO Рассеивание изображения UIImageNamed: FUD

В частности, вы должны уметь:

[UIImage imageWithContentsOfFile:[[UIBundle mainBundle] pathForResource:@"filename" ofType:@"jpeg"]];
person Daniel Dickison    schedule 09.06.2009