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)
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)
名前にもかかわらず、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_getClass
Class はメタ クラスのインスタンスであり、ドキュメントによると「<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
前の答えは正しいですが、質問者の答えではありません。
インスタンス(クラスではない)の場合、「object_getClass(obj)」と「[obj class]」が異なる唯一の理由は、「isa-swizzling」またはインスタンスの「isa」ポインターを変更するその他のスウィズリングです。
インスタンスに「KVO」を追加すると、インスタンスは isa-swizzled になります。Key-Value Observing の実装の詳細を参照してください。
ReactiveCocoa などの他のライブラリも、インスタンスの「isa」ポインタを変更します。( ReactiveCocoa のソースで「RACSwizzleClass」を検索)
このブログ (中国語) も参照してください: Class-swizzling、Isa-swizzling、KVO