5

私が正しく理解していれば、 void *「C の保持可能なポインター型」として分類できます。 したがって、それを Objective-C オブジェクトに割り当てると、暗黙的にブリッジされます。ただし、コンパイラは、明示的なブリッジングが必要であるというエラーを発生させます。

   const void * somePtr = (void *)0x12345678;
   - (void)someMethod:(id)sender
   {
        NSObject *obj = (NSObject *)somePtr;
   }

また、null ポインター定数をチェックしたところ、明示的なブリッジなしでコンパイルされました。

    NSObject *obj = (void *)0;

XCode 4.5(Clang 4.1 (tags/ Apple/clang-421.11.66 ) ( LLVM 3.1svnに基づく)) を使用しています。


質問: NSObject に任意の/無関係なポインターを割り当てるのは少し奇妙ですが、ルールを正しく理解しているかどうかを確認したいと思います。「Cの保持可能なポインタ型」について少し疑問があります。説明; 特に (おそらく修飾された)(おそらく修飾された)の意図について。「C保持可能ポインター型」として分類できるポインター型は何ですか?

また、 「システムグローバル変数」ステートメントによって、実際にはシステムからのグローバル変数を意味しますか?


3.3.2. 既知のセマンティクスを持つ式の保持可能なオブジェクト ポインター型への変換 [Apple 4.0、LLVM 3.1 以降]

次の場合、式は保持に依存しないことが知られています。

  • Objective-C 文字列リテラル、
  • C の保持可能なポインタ型の const システム グローバル変数からのロード、
  • または null ポインター定数。

キャスト オペランドが既知の unretained または既知の keep-agnosticである場合、変換は__bridge キャストとして扱われます。

7.8. C の保持可能なポインター型

型が (修飾されている可能性がある) void へのポインターであるか、(修飾子である可能性がある)構造体またはクラス型へのポインターである場合、その型は C の保持可能なポインター型です。

http://clang.llvm.org/docs/AutomaticReferenceCounting.html

4

2 に答える 2

2

const システムのグローバル変数は、実際には明示的なブリッジングを必要としないようです。つまり、kCFBooleanTrue (CFBoolean インスタンス)、kCFNumberNaN または kABPersonPhoneMobileLabel です。

NSObject *obj = (NSObject *)kCFBooleanTrue;

CFBoolean は無料でブリッジされていませんが、コンパイラによって暗黙的にブリッジされる可能性があることに注意してください。グローバル定数を定義しましたが、暗黙的なブリッジでコンパイルできませんでした。それで、変数がシステムから来ているかどうかをコンパイラがどのように判断できるのだろうか?(または、型が CoreFoundation.framework から来ているかどうかを確認している可能性がありますが、これはきちんとした解決策ではありません...)

- - 編集 - -

ロブ・メイオフの答えを参照して、暗黙のブリッジングを試みましたが、それでもうまくいきませんでした。ファイルを Core Foundation ファイルとして判断するためのコンパイラ フラグがある可能性があります。

NSObject *obj = (NSObject *)myGlobal;

「mytest.h」ファイル

#ifndef mytest_h
#define mytest_h

#pragma clang arc_cf_code_audited begin

typedef const struct MyStruct * MyStructPtr;

CF_EXPORT
const MyStructPtr myGlobal;

#pragma clang arc_cf_code_audited end
#endif

「mytest.c」ファイル

#include "mytest.h"

struct MyStruct {
    int a;
};

static struct MyStruct __myglobal = { 123 };
const MyStructPtr myGlobal = &__myglobal;

- - 編集 - -

CoreFoundation.framework の CFNumber.h ヘッダー ファイルも変更し、CF_IMPLICIT_BRIDGING_ENABLED/CF_IMPLICIT_BRIDGING_DISABLEDを削除してから、プロジェクトをクリーンアップ/ビルドしましたが、これらの定数の暗黙的なブリッジングは無効になりませんでした。

于 2012-11-30T20:37:41.070 に答える
1

リンク先のドキュメントには記載されていませんが、「システム グローバル変数」の「システム」の部分はconst、プラグマが有効な間に変数が定義されたことを意味すると思いますclang arc_cf_code_audited

の上部を見ると、次のCFNumber.hことがわかります。

CF_IMPLICIT_BRIDGING_ENABLED

そして終わり近くにあなたはこれを見つけるでしょう:

CF_IMPLICIT_BRIDGING_DISABLED

これらのマクロは、プラグマCFBase.hを開始および終了するために定義されています。clang arc_cf_code_audited

于 2012-11-30T21:09:08.823 に答える