2009-08-10 6 views
0

J'ai attrapé le journal crash de l'iPhone:Comment s'assurer que UIImage n'est jamais publié?

Exception Type: EXC_BAD_ACCESS (SIGBUS) 
Exception Codes: KERN_PROTECTION_FAILURE at 0x0000000c 
Crashed Thread: 0 

Thread 0 Crashed: 
0 libobjc.A.dylib     0x30011940 objc_msgSend + 20 
1 CoreFoundation     0x30235f1e CFRelease + 98 
2 UIKit       0x308f4974 -[UIImage dealloc] + 36 
3 CoreFoundation     0x30236b72 -[NSObject release] + 28 
4 UIKit       0x30a00298 FlushNamedImage + 64 
5 CoreFoundation     0x30250a20 CFDictionaryApplyFunction + 124 
6 UIKit       0x30a0019c _UISharedImageFlushAll + 196 
7 UIKit       0x30a00730 +[UIImage(UIImageInternal) _flushCacheOnMemoryWarning:] + 8 
8 Foundation      0x3054dc7a _nsnote_callback + 178 
9 CoreFoundation     0x3024ea52 _CFXNotificationPostNotification + 298 
10 Foundation      0x3054b854 -[NSNotificationCenter postNotificationName:object:userInfo:] + 64 
11 Foundation      0x3054dbba -[NSNotificationCenter postNotificationName:object:] + 14 
12 UIKit       0x30a00708 -[UIApplication _performMemoryWarning] + 60 
13 UIKit       0x30a006a0 -[UIApplication _receivedMemoryNotification] + 128 
14 UIKit       0x30a005d0 _memoryStatusChanged + 56 
15 CoreFoundation     0x30217410 __CFNotificationCenterDarwinCallBack + 20 
16 CoreFoundation     0x3020d0aa __CFMachPortPerform + 72 
17 CoreFoundation     0x30254a70 CFRunLoopRunSpecific + 2296 
18 CoreFoundation     0x30254164 CFRunLoopRunInMode + 44 
19 GraphicsServices    0x3204529c GSEventRunModal + 188 
20 UIKit       0x308f0374 -[UIApplication _run] + 552 
21 UIKit       0x308eea8c UIApplicationMain + 960 
... 
... 

De ma question précédente, Can somebody give me a hand about this stacktrace in iPhone app?, j'ai changé mes codes principalement autour d'une partie UIImage. J'utilise maintenant [[UIImage alloc] initWithContentsOfFile ...]. Pas plus [UIImage imageNamed: ...] ou similaire. La partie est ci-dessous.

//this is a method of a subclass of UIImageView. 
    - (void) reviewImage: (bool) review{ 
     NSString* st; 
     if (review){ 
     NSString* origin = [NSString stringWithString: [[ReviewCardManager getInstance] getCardImageString:chosenIndex]]; 
     NSString* stt = [origin substringToIndex: [origin length]-4]; 

     st = [[NSString alloc] initWithString: stt]; 

     if (myImageFlipped == nil) 
     myImageFlipped = [[UIImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource:st ofType:@"png"]]; 
     [self setImage:myImageFlipped]; 

     if (notRotated){ 
      self.transform = CGAffineTransformRotate(self.transform, [MyMath radf:rotate]); 
      notRotated = false; 
     } 
    }else{ 
     st = [[NSString alloc] initWithFormat:@"sc%d", chosenNumber]; 

     if (myImage == nil) 
     myImage = [[UIImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource:st ofType:@"png"]]; 

     [self setImage:myImage]; 

     if (notRotated){ 
      self.transform = CGAffineTransformRotate(self.transform, [MyMath radf:rotate]); 
      notRotated = false; 
     } 

    } 
    [st release]; 
} 

J'ai aussi le UIImage déjà retenu dans la propriété.

@property (nonatomic, retain) UIImage* myImage, *myImageFlipped; 

Mémoire Les fuites ont également été prises en compte. Ces variables sont libérées dans la méthode dealloc.

Je pensais avoir réussi à tuer le bogue, mais il semble que j'ai encore un problème de bogue rare.

Basé sur le journal de plantage, mon application hurle "performMemoryWarning". Je suis juste "alloc" -ing 13 images .png avec la taille 156 x 272. Je suis confus. Ces images ne devraient pas prendre autant de mémoire au point que cela dépasse la RAM de l'iPhone. Ou y a-t-il quelque chose que je néglige? S'il vous plaît donnez votre avis.

+0

Votre propriété semble s'appeler "myImage", mais votre setter s'appelle "setImage:". Pourriez-vous s'il vous plaît expliquer ce qui se passe ici? – hatfinch

+0

Je sous-classe UIImageView et cette classe a 2 UIImage. Quand je veux changer l'image de UIImageView, j'appelle fondamentalement setImage. – Karl

Répondre

0

Le problème est résolu. J'ai oublié de changer UIImage à un endroit. Maintenant, tous les UIImages sont vraiment "alloc", pas plus autorelease. Pour info, si vous utilisez [UIImage imageNamed: ...], utilisez "Simuler l'avertissement de la mémoire" sur iPhone Simulator pour voir si vous rencontrez un problème lorsque le périphérique réel manque de mémoire.

0

Pour vous aider à des problèmes de mémoire et UIImages, vous pouvez utiliser la méthode imageNamed de convience de UIImage, des docs:

This method looks in the system caches for an image object with the specified name and returns that object if it exists. If a matching image object is not already in the cache, this method loads the image data from the specified file, caches it, and then returns the resulting object.

Alternativement, vous pouvez aller this route si vous exécutez toujours dans les problèmes de mémoire après le passage à UIImage imageNamed, car il y a quelques inconvénients à utiliser la méthode convinience.

+0

Non, l'affiche mentionnait déjà qu'ils avaient été * éloignés * de imageNamed, ce qui serait ce que je recommanderais pour répondre à ces avertissements de mémoire, car le cache d'imageNamed est hors de contrôle du programmeur. – hatfinch

+0

Ah, j'ai relu cette section. Dans ce cas, un cache personnalisé comme dans le blog lié aurait alors plus de sens. –

Questions connexes