2012-09-22 26 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)] ]; 
      } 
     } 
    } 
} 

Compilado el código anterior con ARC habilitado. La herramienta Analizar informa una posible pérdida de memoria ya que imageWithCGImage :: devuelve UIImage con recuento +1, luego se pierde la referencia. Leaks Instrument informa que no hay pérdidas de memoria. ¿Que está pasando aqui?Pérdida de memoria con ARC

Además, dado que ARC prohíbe el uso manual de release ect, ¿cómo se soluciona la fuga?

Gracias a cualquiera que pueda ofrecer algún consejo.

Respuesta

8

ARC no administra los tipos C, de los cuales se puede considerar CGImage. Debe liberar el árbitro manualmente cuando haya terminado 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

Consulte también la respuesta aceptada a mi pregunta aquí: http://stackoverflow.com/questions/6260256/what-kind-of-leaks-does-automatic-reference-counting-in-objective-c-not-prevent/6388601 # 6388601 – BoltClock

+0

"La regla de creación dice que cualquier método de interfaz C con" crear "en su nombre devuelve un objeto de fundación +1, que debemos liberar manualmente." - Doh! Por supuesto. Gracias CodaFi! ¡Apreciado! –

+0

@ Z.O. No hay problema. La regla de creación es realmente un poco difícil de encontrar en los documentos, pero es muy importante cuando se trata de las C-Interfaces de Apple. [Aquí está] (https://developer.apple.com/library/mac/documentation/CoreFOundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html#//apple_ref/doc/uid/20001148-103029) (junto con el obtener la regla). – CodaFi

3

Ninguno de la estructura de datos base fundamental se aborda ARC. Muchas veces esto crea un problema. En estos casos, tenemos que liberar manualmente la memoria.