id
が弱参照ポインタである理由と、class
型ポインタをどのように扱うことができるのか、そして実行時にid
に割り当てられるクラスポインタの種類を検出する方法を知りたいのですが。なぜIDは汎用ポインタですか?
答えて
なぜ弱い参照ポインタですか?
id
は、少なくともARC所有権の意味ではない弱い参照ポインタではありません。 id
の型指定されたオブジェクトへの参照が弱いかどうかは、__weak
(およびバリエーション)と宣言されている参照と実際に弱い参照をサポートしているオブジェクトのクラスによって異なります。
しかし、id
はの弱いと入力していると言えますが、ダイナミック/アヒルのタイピングはより正確な説明です。 id
型参照にコンパイル時のクラス型情報が含まれていないため、コンパイラは、実行時エラーを引き起こす可能性のある、下位のオブジェクトが指定されたセレクタに応答できるかどうかを判断できません。
どのようなクラス型ポインタを扱うことができますか?
これはthe Objective-C languageの定義の一部です。コンパイラは、すべてのObjective-Cクラスのスーパータイプとしてid
を認識し、id
を異なる方法で処理します。以下の答えも参照してください。
実行時に、どのタイプのクラスポインタがidに割り当てられているかをどのように検出できますか?
AppleのObjective-Cランタイムでは、オブジェクトに割り当てられたメモリの最初のバイトがそのオブジェクトのクラスを指している必要があります。これはisa
ポインタとして参照されていますが、これはAppleのランタイムがすべてオブジェクトのクラスを検出する方法です。 id
タイプもこの情報を持つように定義されています。実際には、その唯一の属性はisa
ポインタです。つまり、すべて Objective-Cオブジェクトがこの定義に準拠しています。あなたがid
参照を持っているし、参照されたオブジェクトのクラスを発見したい場合
、あなたはそれを-class
を送ることができます:
id someObject;
// Assign something to someObject
// Log the corresponding class
Class c = [someObject class];
NSLog(@"class = %@", c);
// Test whether the object is of type NSString (or a subclass of NSString)
if ([someObject isKindOfClass:[NSString class]]) {
NSLog(@"it's a string");
}
Tagged pointersは、この構造の顕著な偏差であり、(一部)そのため、isa
ポインタに直接アクセスすべきではありません。
一般的なオブジェクト型を使用するといいです。あらゆる種類のオブジェクトを保持できるコレクション型や、オブジェクトの種類がわからなくてもオブジェクトで動作するその他の汎用サービスを定義できます。
idを動作させるためのトリックはありません。バイナリレベルでは、すべてのポインタは互換性があります。彼らは単に数値としてメモリアドレスを表します。 idがあらゆるタイプのポインタを受け入れるようにするには、には、通常はポインタ型の一致が必要なコンパイラの規則を無効にするだけです。
id theObject = // ... something
Class theClass = [theObject class];
NSString *className = NSStringFromClass(theClass);
NSClassDescription *classDescription = [NSClassDescription classDescriptionForClass:theClass];
をしかし、それはコードで物事のこれらの種類を行うために必要なことはまれです:
あなたは方法のこれらの種類のid型変数のクラスについての情報を見つけることができます。より頻繁には、id変数が特定のクラスのインスタンスであるかどうかをテストする必要があります。その場合は、そのクラスにキャストし、その型として扱います。
if ([theObject isKindOfClass:[MySpecializedClass class]]) {
MySpecializedClass *specialObject = (MySpecializedClass *)theObject;
[specialObject doSomethingSpecial];
}
あなたは、クラスを見つけるために-class
を使用していたが、それは、あなたはとにかくそのクラスに基づいてオブジェクトを行うことができ、特別な何もない、あなたがについて何も知らないクラスを返された場合。したがって、あなたが知っているクラスと一致するかどうかをチェックするだけで、そのクラスのために特別な処理を行うつもりならば、何もする必要はありません。
isKindOfClass
の代わりにisMemberOfClass
を使用することがあります。正確に一致するか、サブクラスを含めるかによって異なります。
id
という内部構造を見つけるために、ヘッダファイルobjc/objc.hを調べる価値があります。
typedef struct objc_class *Class;
typedef struct objc_object {
Class isa;
} *id;
typedef struct objc_selector *SEL;
typedef id (*IMP)(id, SEL, ...);
- 1. 汎用ポインタが汎用参照によってキャプチャされないのはなぜですか?
- 2. java.util.Map.get(...)が汎用ではないのはなぜですか?
- 3. 汎用ビューを使用するのはなぜですか?
- 4. 汎用クラスを汎用インターフェイスに変換できません。なぜですか?
- 5. なぜ機能ポインタは `constexpr`ですか?
- 6. Juliaは汎用プログラミングに適していないのはなぜですか?
- 7. 汎用DAOインターフェイスのメソッドにデフォルトアクセスを使用するのはなぜですか?
- 8. なぜNIO.2 FileVisitorタイプが汎用ですか?
- 9. なぜcharポインタを使用できないのですか?
- 10. std :: applyが汎用関数で失敗するのはなぜですか?
- 11. なぜcallocポインタ型がvoid *ですか?
- 12. Javaでポインタを使用できないのはなぜですか?
- 13. MongoDBなぜIDは-1ですか?
- 14. フォームがVS IDEに汎用名を表示するのはなぜですか?
- 15. なぜポインタがポインタよりも安全ですか?
- 16. ポインタ変換で(void *)が必要なのはなぜですか?
- 17. これらの関数で異なるポインタとvoidポインタが使用されるのはなぜですか?
- 18. なぜオブジェクトの汎用型のみですか?私は何を意味
- 19. rpbとrspが汎用レジスタと呼ばれるのはなぜですか?
- 20. ワイルドカードを汎用クラス&メソッド宣言で使用できないのはなぜですか?このような
- 21. 汎用リポジトリでEntityとIDを渡すには?
- 22. 非汎用タスク(C#4.0以降)でタスクの結果プロパティを使用できないのはなぜですか?
- 23. 非IDカラムのHibernate汎用クエリメソッド?
- 24. なぜJava Calendarはフィールドを汎用フィールドではなく配列に格納するのですか?
- 25. ポインタにセグメンテーションフォルトが発生するのはなぜですか?
- 26. なぜResponse.StatusCode =(int)HttpStatusCode.NotFoundは私に汎用エラーハンドラを与えますか?
- 27. current_userポインタがリセットされるのはなぜですか?
- 28. 滑らかな汎用テーブル
- 29. Java汎用オブジェクトNullポインタチェックNullポインタ例外をスローする
- 30. なぜintポインタ '++'は1ではなく4だけインクリメントするのですか?