2009-06-08 3 views
3

Ich schreibe eine Anwendung, die etwa 40 44-KB-JPEGs gleichzeitig im Speicher halten muss. Ich habe gehört, dass Anwendungen etwa 22 Megabyte verwenden können, bevor sie eine Warnmeldung zu wenig Speicher auslösen, also bin ich mir ziemlich sicher, dass dies möglich sein sollte. Sobald jedoch gehe ich um ein Megabyte geladen werden, beginnen diese Meldungen in der Konsole Aufspringen:Warum verbraucht das Laden von mehr als einem Megabyte von Bildern den gesamten Speicher meines iPhones?

 
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... 

Dann ist es mir wieder auf dem Home-Bildschirm Dumps.

Hier ist der Code, den ich über die Bilder laden:

#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 

Gibt es etwas, was ich falsch hier? Können iPhone-Anwendungen wirklich nur ein Megabyte Speicher verwenden?

Antwort

15

Wenn Sie ein komprimiertes Bild, z. B. ein JPEG-Bild, laden, wird es normalerweise unkomprimiert (da dies erforderlich ist, damit Sie etwas Nützliches mit dem Bild tun können, z. B. Anzeigen oder Bearbeiten).

Das unkomprimierte Bild wird definitiv größer sein als das 44 KiB das komprimierte Bild im JPEG Format belegt (etwa 3 oder 4 Bytes multipliziert mit Breite und Höhe). Daher haben Sie weniger Speicher als Sie denken, wenn Sie nur die JPEG-Größen betrachten. Wenn Sie wirklich nur die JPEGs im Speicher halten müssen (und nichts mit ihnen tun, nur sie halten), können Sie den rohen Bytestrom nur im Speicher speichern und ihn dann nur dann als Bild laden, wenn Sie ihn wirklich brauchen .

Aber es kann andere Alternativen geben, je nachdem, was Sie tun müssen. Brauchen Sie wirklich alle Bilder im Speicher? Können Sie das Laden eines einzelnen Bildes verzögern, bis es benötigt wird (und andere zu diesem Zeitpunkt entladen), um Speicherplatz zu sparen? Benötigen Sie nur bestimmte Informationen aus jedem Bild, die zwischengespeichert werden können (und danach brauchen Sie das Bild nicht mehr selbst)? usw.

+0

Dank für das half es. Ich habe es die JPEG-Daten für die Bilder mit voller Auflösung im Speicher behalten und viertel Auflösung Bilder beim Ändern oder Laden von Bildern. Danke! –

1

imageNamed: wird die Bilddaten und dekomprimieren die uncompressed Daten zwischenzuspeichern. Ich glaube, es wird Ihnen gut gehen, wenn Sie imageWithContentsOfFile: verwenden, da diese Methode nur die komprimierten Daten speichert und sie beim Zeichnen dekodiert.

Siehe die Antwort für die SO Dispelling the UIImage imageNamed: FUD

Insbesondere in Frage, sollten Sie in der Lage zu tun: die Erklärung

[UIImage imageWithContentsOfFile:[[UIBundle mainBundle] pathForResource:@"filename" ofType:@"jpeg"]];