2012-09-22 13 views
7
+(void)setup { 
    UIImage* spriteSheet = [UIImage imageNamed:@"mySpriteSheet.png"]; 
    CGRect rect; 
    animation = [NSMutableArray arrayWithCapacity:numberOfFramesInSpriteSheet]; 
    int frameCount = 0; 

    for (int row = 0; row < numberFrameRowsInSpriteSheet; row++) { 
     for (int col = 0; col < numberFrameColsInSpriteSheet; col++) { 
      frameCount++; 
      if (frameCount <= numberOfFramesInSpriteSheet) { 
       rect = CGRectMake(col*frameHeight, row*frameWidth, frameHeight, frameWidth); 
       [animation addObject:[UIImage imageWithCGImage:CGImageCreateWithImageInRect(spriteSheet.CGImage, rect)] ]; 
      } 
     } 
    } 
} 

Compilato il codice precedente con ARC abilitato. Lo strumento Analizza segnala una possibile perdita di memoria dal momento che imageWithCGImage: restituisce UIImage con il conteggio +1, quindi il riferimento viene perso. Leaks Instrument non segnala alcuna perdita di memoria. Cosa sta succedendo qui?Perdita di memoria con ARC

Inoltre, poiché ARC proibisce l'utilizzo manuale di release ect, come si aggiusta la perdita?

Grazie a chiunque possa offrire qualche consiglio.

risposta

8

ARC non gestisce i tipi C, di cui CGImage può essere considerato. È necessario rilasciare l'arbitro manualmente quando si è finito con CGImageRelease(image);

+(void)setup { 
    UIImage* spriteSheet = [UIImage imageNamed:@"mySpriteSheet.png"]; 
    CGRect rect; 
    animation = [NSMutableArray arrayWithCapacity:numberOfFramesInSpriteSheet]; 
    int frameCount = 0; 

    for (int row = 0; row < numberFrameRowsInSpriteSheet; row++) { 
     for (int col = 0; col < numberFrameColsInSpriteSheet; col++) { 
      frameCount++; 
      if (frameCount <= numberOfFramesInSpriteSheet) { 
       rect = CGRectMake(col*frameHeight, row*frameWidth, frameHeight, frameWidth); 
       //store our image ref so we can release it later 
       //The create rule says that any C-interface method with "create" in it's name 
       //returns a +1 foundation object, which we must release manually. 
       CGImageRef image = CGImageCreateWithImageInRect(spriteSheet.CGImage, rect) 
       //Create a UIImage from our ref. It is now owned by UIImage, so we may discard it. 
       [animation addObject:[UIImage imageWithCGImage:image]]; 
       //Discard the ref. 
       CGImageRelease(image); 
      } 
     } 
    } 
} 
+2

Vedere anche la risposta accettata alla mia domanda qui: http://stackoverflow.com/questions/6260256/what-kind-of-leaks-does-automatic-reference-counting-in-objective-c-not-prevent/6388601 # 6388601 – BoltClock

+0

"La regola di creazione dice che qualsiasi metodo C-interface con" create "nel suo nome restituisce un oggetto di base +1, che dobbiamo rilasciare manualmente." - doh! Ovviamente. Grazie CodaFi! Apprezzato! –

+0

@ Z.O. Nessun problema. La regola di creazione è in realtà un po 'difficile da trovare nei documenti, ma è molto importante quando si ha a che fare con le C-Interfacce di Apple. [Eccolo qui] (https://developer.apple.com/library/mac/documentation/CoreFOundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html#//apple_ref/doc/uid/20001148-103029) (insieme al ottieni la regola). – CodaFi

3

Nessuno della struttura dei dati nucleo fondante è trattata con ARC. Molte volte questo crea un problema. In questi casi dobbiamo rilasciare manualmente la memoria.