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

Đã biên dịch mã trên với ARC được bật. Công cụ phân tích báo cáo rò rỉ bộ nhớ có thể xảy ra vì imageWithCGImage :: trả về UIImage với số +1, sau đó tham chiếu bị mất. Rò rỉ Instrument báo cáo không có rò rỉ bộ nhớ nào cả. Những gì đang xảy ra ở đây?Rò rỉ bộ nhớ với ARC

Hơn nữa, vì ARC cấm sử dụng bằng tay release ect, cách khắc phục sự cố rò rỉ?

Nhờ bất kỳ ai có thể đưa ra bất kỳ lời khuyên nào.

Trả lời

8

ARC không quản lý loại C, trong đó CGImage có thể được xem xét. Bạn phải nhả ref cách thủ công khi bạn đã kết thúc với 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

Đồng thời xem câu trả lời được chấp nhận cho câu hỏi của tôi tại đây: http://stackoverflow.com/questions/6260256/what-kind-of-leaks-does-automatic-reference-counting-in-objective-c-not-prevent/6388601 # 6388601 – BoltClock

+0

"Quy tắc tạo cho biết rằng bất kỳ phương thức giao diện C nào có" tạo "trong tên của nó đều trả về đối tượng nền tảng +1, mà chúng tôi phải phát hành theo cách thủ công". - doh! Tất nhiên. Cảm ơn CodaFi! Đánh giá cao! –

+0

@ Z.O. Không vấn đề gì. Các quy tắc tạo ra thực sự là một chút khó khăn để tìm thấy trong các tài liệu, nhưng nó rất quan trọng khi giao dịch với C-Interfaces của Apple. [Đây là] (https://developer.apple.com/library/mac/documentation/CoreFOundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html#//apple_ref/doc/uid/20001148-103029) (cùng với nhận quy tắc). – CodaFi

3

Không ai trong số các lõi cấu trúc dữ liệu cơ sở được xử lý ARC. Nhiều lần điều này tạo ra một vấn đề. Trong trường hợp này, chúng ta phải giải phóng bộ nhớ một cách thủ công.