17

我最近開始使用自動引用計數(ARC)的新項目。
當我分配的CALayer的內容:ARC是否與Core Graphics對象一起工作?

UIView* view = ... 
UIImage* image = ... 
view.layer.contents = image.CGImage 

我得到一個錯誤

非Objective-C的指針類型 'CGImageRef' 到 'ID' 的隱式轉換是不允許與ARC

簡單地將CGImageRef轉換成id隱藏了錯誤,但我想知道ARC是否仍能正常工作呢?

回答

42

您應該確實查看WWDC 2011上的ARC視頻。它們可在開發者網站上找到並通過iTunes打開。尤其是:

•會話323 - 引入自動引用計數

•會話322 - Objective-C的進步在深度

此外,ARC參考筆記:

https://developer.apple.com/library/content/releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html

參考筆記和視頻都討論了Core Graphics(等)以及它們如何與ARC一起工作。

詳細的,請看稱爲「管理免費電話橋接」

在很多Cocoa應用程序的部分,你需要使用Core Foundation的風格對象,無論從核心基礎框架本身(如如 CFArrayRef或CFMutableDictionaryRef)或者採用核心圖形等核心基金會約定(您可能使用類型爲 ,如CGColorSpaceRef和CGGradientRef)的框架採用 。

編譯器不會自動管理Core的基線對象的生命週期;您必須調用CFRetain和CFRelease(或 對應的特定於型號的變體),如Core基金會內存管理規則(請參閱內存管理編程指南 指南)規定的。

如果Objective-C和核心基礎風格的對象之間投射,您 需要告知使用一個投對象 的所有權語義的編譯器(在objc/runtime.h所定義)或核心 基礎式宏(在NSObject.h中定義):[...]

JörgJacobsen對橋接選項也有很好的總結概述:Managing Toll-free Bridging in an ARC’ed Environment

__bridge_retained(n.b.):僅當從對象指針投射到C類型指針時才使用它):我(程序員)需要在C類型指針的黑暗世界中引用此對象 一段時間,這對於 ARC,您是不透明的。所以,請不要發佈這個對象,而我仍然需要它 。我(程序員)承諾釋放它自己(在黑暗中 世界),當我用它

__bridge_transfer做(注意:只能在C類型的指針鑄造時對象的指針使用它):我(程序員)交給你,ARC,一個我自己擁有的對象,並且我不再對那些對你來說不透明的C型指針的黑暗世界感興趣。每當你,ARC, 完成與該對象,請自行釋放它,因爲你知道正確的時間,從而節省我一些工作,而不必自己做。

__bridge:ARC,你繼續平衡你的保留和釋放,因爲我一直在C類指針的黑暗世界這 是平衡了我的...。每當我需要在黑暗世界中堅持一個物體時,我會自己保留它,並在適當的時候釋放它。我不需要任何 額外的合同,ARC。

+0

非常有幫助和完整的答案,非常感謝 – Pieter

+0

:)謝謝!很高興我能幫上忙!我們幾天前遷移了一個相當大的應用程序,花了大約兩天的時間來解決所有問題,但對於最終結果我感到非常滿意。少得多的代碼,更強大。 ARC非常酷。這些視頻對我來說是一個很棒的資源。 – Steve

+0

+1引用Jorg Jacobsen的解釋。 – jAckOdE

8

儘管Steve引用了參考文獻,但我相信您在上面展示的案例可能是特殊的。從Transitioning to ARC Release Notes,要注意部分「的編譯器處理CF對象返回可可方法」:

,編譯器理解Objective-C的方法,返回核心 基金類型順應歷史可可命名約定(見 高級內存管理編程指南)。例如, 編譯器知道,在iOS中,由CGColor 方法UIColor返回的CGColor不是擁有的。

的代碼示例他們提供:

gradientLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor darkGrayColor] CGColor], 
               (id)[[UIColor lightGrayColor] CGColor], nil]; 

依靠CGColors從這些方法已知的回報(他們缺少演員與我在上面的代碼中已經添加了ID,這應該是儘快在他們的文件中糾正)。

因爲[image CGImage]遵循命名約定,我相信CGImage會在這裏正確橋接。我認爲你的演員陣容應該是你需要的一切。

4

layer.contents = (id)image.CGImage問題的一個受歡迎的答案是layer.contents = obj_unretainedObject(image.CGImage)

我做=(__bridge id)image.CGImage

+0

我建議將代碼格式添加到您的答案中,以提高可讀性。 –

相關問題