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)] ]; 
      } 
     } 
    } 
} 

Kompiliert den obigen Code mit aktiviertem ARC. Das Analyse-Tool meldet einen möglichen Speicherverlust, da imageWithCGImage :: den Wert UIImage mit dem Wert +1 zurückgibt. Dann ist der Verweis verloren. Leaks Instrument meldet überhaupt keine Speicherlecks. Was ist denn hier los?Speicherleck mit ARC

Darüber hinaus, da ARC die Verwendung von manuell mit release ect verbietet, wie repariert man das Leck?

Vielen Dank an jeden, der Ihnen einen Rat geben kann.

Antwort

8

ARC verwaltet keine C-Typen, von denen CGImage in Betracht gezogen werden kann. Sie müssen die ref manuell freigeben, wenn Sie mit 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

Siehe auch die akzeptierte Antwort auf meine Frage hier: http://stackoverflow.com/questions/6260256/what-kind-of-leaks-does-automatische-reference-counting-in-objective-c-not-prevent/6388601 # 6388601 – BoltClock

+0

"Die create-Regel besagt, dass jede C-Interface-Methode mit" create "in ihrem Namen ein +1-Fundament-Objekt zurückgibt, das wir manuell freigeben müssen." - Dah! Na sicher. Danke CodaFi! Geschätzt! –

+0

@ Z.O. Kein Problem. Die Erstellungsregel ist in den Dokumenten zwar etwas schwer zu finden, aber sie ist sehr wichtig im Umgang mit C-Interfaces von Apple. [Hier ist es] (https://developer.apple.com/library/mac/documentation/CoreFOundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html#//apple_ref/doc/uid/20001148-103029) (zusammen mit der Regel bekommen). – CodaFi

3

Keine der Kerndatengrundstruktur mit ARC wird behandelt fertig sind. Viele Male verursacht dies ein Problem. In diesem Fall müssen wir den Speicher manuell freigeben.