1. ホーム
  2. objective-c

[解決済み] Objective-C:idとvoidの違い*。

2022-04-22 14:30:46

質問

とはどのような違いがあるのでしょうか? idvoid * ?

解決方法は?

void * は、「型付けされていない/内容が不明な、ランダムなメモリチャンクへの参照」を意味します。

id は、クラス不明のランダムなObjective-Cオブジェクトへの参照を意味します。

さらに意味上の違いもあります。

  • GC Only または GC Supported モードでは、コンパイラは、型 id には適用されませんが void * . 構造体を宣言する場合、この差は致命的なものになる可能性があります。 のようなiVarsの宣言は void *_superPrivateDoNotTouch; の場合、オブジェクトの刈り取りが早まります。 _superPrivateDoNotTouch が実際にオブジェクトであることを示します。 そんなことはしないでください。

  • の参照に対してメソッドを呼び出そうとしている。 void * という型があると、コンパイラの警告が出ます。

  • に対してメソッドを呼び出そうとすると id 型のいずれでも宣言されていない場合にのみ警告されます。 @interface の宣言は、コンパイラが見ることができます。

従って、決してオブジェクトを void * . 同様に id 型変数でオブジェクトを参照することができます。 できるだけ具体的なクラスの型付けされた参照を使用する。 例えば NSObject * よりも優れています。 id なぜなら、少なくともコンパイラはその参照に対するメソッド呼び出しの検証をより良く行うことができるからです。

の一般的で有効な使い方は void * は、他の API を通して渡される不透明なデータ参照として使用されます。

を考えてみましょう。 sortedArrayUsingFunction: context: のメソッドを使用します。 NSArray :

- (NSArray *)sortedArrayUsingFunction:(NSInteger (*)(id, id, void *))comparator context:(void *)context;

ソート関数は、次のように宣言される。

NSInteger mySortFunc(id left, id right, void *context) { ...; }

この場合、NSArrayは単にあなたが context としてメソッドの引数に渡します。 context 引数で指定します。 これは、NSArrayに関する限り、ポインタサイズのデータの不透明な塊であり、どのような目的にも自由に使用することができます。

クロージャ型の機能がない言語では、これが関数と一緒にデータの塊を持ち運ぶ唯一の方法です。 たとえば、mySortFunc() で大文字小文字を区別するかしないかを条件付きでソートし、かつスレッドセーフにしたい場合、コンテキストで is-case-sensitive インジケータを渡し、入りと出でキャストを行うことになるでしょう。

脆弱でエラーが起こりやすいですが、唯一の方法です。

ブロックはこれを解決する -- ブロックはCのクロージャであり、Clangで利用可能である --。 http://llvm.org/ で、Snow Leopardでは広く浸透しています ( http://developer.apple.com/library/ios/documentation/Performance/Reference/GCD_libdispatch_Ref/GCD_libdispatch_Ref.pdf ).