2012-03-13 110 views
21

更新:此問題已修復Xcode 4.6!強烈@property與__attribute __((NSObject))爲CF類型不保留

此技術現在可以按照預期工作。但是,在您使用代碼之前,請務必閱讀Rob Napier最佳答案頂部的註釋。

ORIGINAL POST

(ARC時,Xcode 4.3.1的iOS 5.1)

我有CF型(CGImage),我要通過使用__attribute__((NSObject)) ARC自動管理的強大的屬性(例如在合成的setter中保留&版本,並且它在dealloc中被刪除),但它不起作用:當我分配屬性時,該對象不會保留。

的最小例子重現:

@interface TestClass : NSObject 
@property (nonatomic, strong) __attribute__((NSObject)) CFStringRef str; 
@end 

// ...In some function 
CFStringRef str = (__bridge CFStringRef)[NSString stringWithFormat:@"%g", 2.5]; 
NSLog(@"%ld", CFGetRetainCount(str)); 
TestClass *obj = [[TestClass alloc] init]; 
obj.str = str; 
NSLog(@"%ld", CFGetRetainCount(str)); 

哪個打印 '1' 的兩倍。我覺得它工作正常之前我更新到iOS 5.1 & Xcode 4.3.1(從iOS 5 & Xcode 4.2),並從它切換到gdb到lldb。沒有升級(或知道如何改回編譯器)的人可以確認嗎?

+0

解決方法之一就是使用'NSString *'屬性,並在分配時使用'__bridge'屬性。 – jtbandes 2012-03-13 13:59:48

+0

我沒有從[此鏈接](http://clang.llvm.org/docs/AutomaticReferenceCounting.html#objects.operands.casts)得到任何東西,希望你得到一些東西 – 2012-03-13 14:42:42

+0

不幸的是,這只是一個重現的例子,在我使用的實際代碼中,我有一個CGImage。我將編輯帖子。 – 2012-03-13 18:50:31

回答

33

EDIT2(MAR 2013年) FYI對於那些對此技術感興趣,ARC documentation for clang包括以下注意事項:

不推薦使用__attribute__((NSObject))類型定義。如果使用這個屬性是絕對必要的,要非常明確地使用typedef,並且不要認爲它會被諸如__typeof之類的語言特性和C++模板參數替換保留。

理由

任何編譯器操作順帶條從類型鍵入「糖」將產生一個類型沒有屬性,這可能會導致意想不到的行爲。下面


編輯很有趣,但很可能無關緊要。這是一個錯誤,你應該打開雷達。正如@lnafziger所指出的,這是合法的,應該受到尊重。這個錯誤是,當你包含nonatomic時,它是不被尊重的。如果你刪除nonatomic,那麼它的工作原理。 nonatomic定義中沒有任何內容表明這是設計。


這是一種聰明,但我想我明白了爲什麼它不工作。您可以通過生成彙編程序並注意到setStr:不會調用objc_storeStrong()來確認。它做了一個簡單的分配。

的問題是,你的屬性定義不符合一個可保持對象的指針的定義(強調):

阿可保持對象的指針(或可保持指針)是 可保持對象的值指針類型(可保留類型)。有三種 種可保持對象指針類型的:

  • 塊指針
  • Objective-C的對象的指針(ID,類,NSFoo(通過將插入符號(^)聲明符印記到 函數型形成的) *等)
  • 的typedef標有__attribute __((NSObject的))

你創建一個typedef作爲指定?不,你沒有。好的,那我們怎麼做呢?

typedef __attribute__((NSObject)) CFStringRef MYStringRef; 

@interface TestClass : NSObject 
@property (nonatomic, strong) MYStringRef str; 
@end 

... the rest of your code ... 

這將打印「1」,然後「2」,因爲我假設你期望。害怕我不明確的原因,但看看彙編輸出,一切似乎都很好,我想不出任何具體問題或違規。

你可能有理由爲此打開雷達。至少,即使有文檔記載,typedef不會被視爲指定類型的事實至少令人驚訝。

編輯:從ObjC Programming Language注意到@ lnafziger的評論,肯定是要麼在ARC規範/執行錯誤或鏈接的文檔中的錯誤,因此他們中的一個應該是固定的。

+5

打開雷達。很高興你能找到它的工作順利的條件。 – 2012-03-13 19:55:42

+0

+1很好的答案! – lnafziger 2012-03-14 00:17:46

+2

如果您確實打開了雷達,請在此處張貼#。 – bbum 2012-10-10 16:43:30