2012-10-06 67 views
5

我想要一個簡單的測試了一個更復雜的項目,但我感到困惑,爲什麼下面的代碼崩潰,並給予一個EXC_BAD_ACCESS錯誤?的UIImage從CGImageRef

這是從一個UIView調用。我的猜測是CGImageRef沒有被保留,而是添加了CGImageRetain(imageRef);我的猜測是CGImageRef不被保留,但添加了C​​GImageRetain(imageRef);沒有區別。

我也應該注意到,該項目已ARC打開。

編輯

我確實有點更多的測試,並發現這是直接關係到ARC爲我創造了2個基本項目,包括只有上面的代碼。 ARC的第一個關閉,它完美的工作。與ARC打開的下一個和BAM崩潰與相同的錯誤。有趣的是,我第一次在崩潰之前運行項目時纔得到實際的日誌錯誤。

Error: ImageIO: ImageProviderCopyImageBlockSetCallback 'ImageProviderCopyImageBlockSetCallback' header is not a CFDictionary... 

回答

9

這條線的問題是:

CGImageRef imageRef = [[[UIImage alloc]initWithContentsOfFile:imagePath]CGImage]; 

創建的UIImage將被立即釋放這之後全表達式(例如,在這一行之後)。所以,即使試圖添加CGImageRetain()之後也不起作用。

最根本的問題是從CGImage返回CGImageRef幾乎可以肯定是UIImage的伊娃當UIImage被deallocted將被釋放。

通用的方式來解決,這是延長UIImage的壽命。您可以通過將UIImage到一個局部變量,你的最後一個引用CGImage(例如用(void)uiimageVar)後引用它做到這一點。或者,你可以在同一條線上保留CGImageRef,如

CGImageRef imageRef = CGImageRetain([[[UIImage alloc] initWithContentsOfFile:imagePath] CGImage]); 

但是,如果你這樣做,不要忘記釋放imageRef時,即可大功告成。

5

你寫這樣的:

CGImageRef imageRef = [[[UIImage alloc]initWithContentsOfFile:imagePath]CGImage]; 

這行創建了一個UIImage,獲取其CGImage屬性,然後釋放UIImage對象。由於您沒有保留該線上的CGImage,因此CGImage的唯一所有者是UIImage。所以當UIImage發佈並立即釋放時,它也會釋放CGImage

您需要保留CGImage被釋放UIImage之前。試試這個:

CGImageRef imageRef = CGImageRetain([[UIImage alloc]initWithContentsOfFile:imagePath].CGImage); 

,然後在函數的末尾:

CGImageRelease(imageRef); 
+0

奇妙的,現在我看到究竟是怎麼回事。至少我是在正確的軌道上。感謝Rob。 – EcksMedia