2012-03-13 4 views
21

UPDATE:この問題はXcode 4.6で修正されました!CFタイプの__attribute __((NSObject))を持つ強い@propertyは保持されません

このテクニックは、再び意図どおりに機能します。しかし、あなたのコードで使用する前に、Rob Napierの優れた答えの一番上にあるノートを必ず読んでください。

ORIGINAL POST

(ARC、Xcodeの4.3.1、iOSの5.1)

私は自動的に__attribute__((NSObject))を使用してARCによって管理されるようにしたいというCFタイプ(CGImage)の強い性質を持っています(合成セッターに&のリリースを保持していて、deallocではnilされているように)、動作しません。プロパティを割り当てると、オブジェクトは保持されません。再現する

最小限例:

二回 '1' を出力します
@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)); 

今、奇妙なことが(私はこれのか分からないが)、私はiOSの5.1(iOSの5 & Xcodeの4.2から)&のXcode 4.3.1にアップデート、およびそれに切り替わる前に、それが正常に働いていたと思うということですgdbからlldbへアップグレードしていない(またはコンパイラの変更方法を知っている)人がおそらく確認できるのでしょうか?この技術に興味のある人のための

+0

解決策の1つは、単純にNSString *プロパティを使用し、割り当て時に__bridgeキャストを使用することです。 – jtbandes

+0

私は[このリンク](http://clang.llvm.org/docs/AutomaticReferenceCounting.html#objects.operands.casts)から何かを得ることはできません –

+0

残念ながらこれは再現するための単なる例ですが、私の実際のコードで私はCGImageを使用しています。私は投稿を編集します。 –

答えて

33

EDIT2(2013年3月)はFYI、ARC documentation for clangは、以下の注意事項が含まれています

__attribute__((NSObject))のtypedefの使用は推奨されません。この属性を絶対に使用する必要がある場合は、typedefの使用については非常に明示し、__typeofやC++テンプレート引数の置換などの言語機能によって保持されるとは想定しないでください。

理由

ちなみにタイプから「砂糖」と入力ストリップどれコンパイラの操作が予期しない動作が発生する可能性がある、属性を持たないタイプが得られます。


EDIT以下の興味深い、おそらく無関係です。これはバグで、レーダーを開くべきです。 @lnafzigerが指摘したように、これは合法であり、尊敬されるはずです。バグは、nonatomicを含めると賞賛されないということです。 nonatomicを削除すると動作します。 nonatomicの定義のどれも、これが仕様であることを示していません。


これは賢いですが、なぜ機能していないのでしょうか。アセンブラを生成し、setStr:objc_storeStrong()を呼び出さないことに注意して、動作していないことを確認できます。それは単純な割り当てを行います。

問題は、あなたの財産の定義が保持できるオブジェクトポインタ(強調追加)の定義に準拠していないということです。

保持可能オブジェクトポインタ(または保持可能ポインタが) 保持可能オブジェクトの値でありますポインタタイプ(保持可能タイプ)。

  • Objective-Cのオブジェクトポインタ(ID、クラス、NSFoo( 関数型にキャレット(^)宣言子シギルを適用することによって形成される)

    • ブロックポインタ:保持可能オブジェクトのポインタ型の三 種類があります*など)__attribute __((NSObjectの)が付い
    • のtypedef
  • 指定されたとおり、あなたがのtypedefを作成しましたか?いいえ、あなたはしませんでした。 OK、どうやってこれをやるの?

    「1」と「2」が表示されます。私は不特定の理由で私を怖がらせるが、アセンブラの出力を見ると、すべてがうまくできていると私はここで特定の問題や違反を考えることはできません。

    あなたはこれのためにレーダーを開くことが正当化できます。 typedefが指定された型と同じように扱われないという事実は、少なくとも文書化されていても驚くべきことです。

    EDIT:ObjC Programming Languageから留意する@ lnafzigerさんのコメントには、間違いなく、ARC仕様/実装におけるエラーまたはリンクされたドキュメント内のエラーなので、そのうちの一つが固定されなければならないのいずれかがあります。

    +5

    レーダーを開いた。ニースあなたはそれが動作する条件を見つけることができましたbtw。 –

    +0

    +1すてきな答え! – lnafziger

    +2

    レーダーを開けた場合は、ここに#を記入してください。 – bbum

    関連する問題