6

object_getClass(obj) と [obj class] を呼び出すと、2 つの異なるオブジェクト インスタンスが取得されます。理由はありますか?

Class cls = object_getClass(obj);
Class cls2 = [obj class];

(lldb) po cls
$0 = 0x0003ca00 Test
(lldb) po cls2
$1 = 0x0003ca14 Test
(lldb) 
4

2 に答える 2

12

名前にもかかわらず、obj はクラスであると思われます。例:

Class obj = [NSObject class];
Class cls = object_getClass(obj);
Class cls2 = [obj class];
NSLog(@"%p",cls);  // 0x7fff75f56840
NSLog(@"%p",cls2); // 0x7fff75f56868

その理由は、Class オブジェクトのクラスは同じクラスですがobject_getClass、Class の はメタ クラス (クラスのクラス) だからです。object_getClassClass はメタ クラスのインスタンスであり、ドキュメントによると「<em>The class object of which object is an instance」を返すため、これは理にかなっています。LLDB の出力は次のようになります。

(lldb) p cls
(Class) $0 = NSObject
(lldb) p cls2
(Class) $1 = NSObject
(lldb) po cls
$2 = 0x01273bd4 NSObject
(lldb) po cls2
$3 = 0x01273bc0 NSObject

に置き換えるClass obj = [NSObject class];NSObject *obj = [NSObject new];、cls と cls2 を印刷するときの結果は同じになります。あれは、

    NSObject *obj = [NSObject new];
    Class cls = object_getClass(obj);
    Class cls2 = [obj class];
    NSLog(@"%p",cls);  // 0x7fff75f56840
    NSLog(@"%p",cls2); // 0x7fff75f56840
于 2013-04-09T16:11:32.933 に答える
3

前の答えは正しいですが、質問者の答えではありません。

インスタンス(クラスではない)の場合、「object_getClass(obj)」と「[obj class]」が異なる唯一の理由は、「isa-swizzling」またはインスタンスの「isa」ポインターを変更するその他のスウィズリングです。

インスタンスに「KVO」を追加すると、インスタンスは isa-swizzled になります。Key-Value Observing の実装の詳細を参照してください。

ReactiveCocoa などの他のライブラリも、インスタンスの「isa」ポインタを変更します。( ReactiveCocoa のソースで「RACSwizzleClass」を検索)

このブログ (中国語) も参照してください: Class-swizzling、Isa-swizzling、KVO

于 2016-01-27T12:32:15.963 に答える