2015-11-22 81 views
0

我維護一些在非ARC環境中實現的遺留代碼。以下代碼段中是否有內存管理問題? (即,tImage被保留在塊和將永遠不會被釋放。)塊如何在非ARC環境中保留變量?

+ (void)noCacheImageWithName:(NSString *)name completion:(imageload_block_t)imageLoadBlock 
{ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     UIImage *tImage = [UIImage imageWithContentsOfFile:<#image_path#>]; 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      imageLoadBlock(tImage); 
     }); 
    }); 
} 

UPDATE

我在代碼段中提到的block是在主隊列中的block

+0

你似乎誤解了塊爲什麼會導致保留週期。你的'tImage'確實有對這個塊的引用,是嗎? –

+0

@TheParamagneticCroissant我認爲這個塊是'NSConcreteStackBlock'類型,不會被'tImage'保留。在塊中使用'tImage'時,'tImage'的引用計數會增加,但是沒有相應的釋放操作。 – jam

+1

如果'tImage'沒有引用塊,那麼保留週期就不可能。 「沒有相應的釋放操作」 - 這是一件好事。 'tImage'不是由'new'或'alloc'創建的,所以它是自動釋放的 - 它不能**被明確釋放。 –

回答

1

dispatch_async()將複製傳遞給它的塊,因爲它需要該塊來存活調用者的範圍。該塊捕獲tImage的值。所以,當該塊被複制時,它將保留指向UIImage的對象。

當然,GCD將確保塊的副本在執行後被釋放。當該塊被釋放時,它將釋放它保留的任何東西。這包括tImage指向的UIImage對象。

因此,就dispatch_async(),GCD和塊運行時間而言,所有內容都是平衡的。

假設imageLoadBlock()在內存管理方面表現良好,該代碼沒有問題。