object_getClass(obj)和[obj class]给出不同的结果

问题描述 投票:4回答:2

当调用object_getClass(obj)和[obj class]时,我得到了两个不同的对象实例。知道为什么吗?

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

(lldb) po cls
$0 = 0x0003ca00 Test
(lldb) po cls2
$1 = 0x0003ca14 Test
(lldb) 
objective-c cocoa-touch objective-c-runtime
2个回答
11
投票

我怀疑obj(尽管有名称)是一个类。示例:

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

原因是Class对象的类是相同的类,但是Class的object_getClass是元类(类的类)。这是有道理的,因为Class是元类的实例,并且根据文档,object_getClass返回“ 该对象是实例的类对象”。 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

3
投票

上一个答案是正确的,但对于发问者却不是。

对于实例(不是类),“ object_getClass(obj)”和“ [obj类]”不同的唯一原因是“ isa混乱”或其他更改实例的“ isa”指针的混乱。

[当您将'KVO'添加到实例时,该实例被isa-swiizzed。参见Key-Value Observing Implementation Details

[ReactiveCocoa等其他一些库也将更改实例的'isa'指针。(在Source of ReactiveCocoa中搜索“ RACSwizzleClass”)

另请参见此博客(中文):Class-swizzling, Isa-swizzling and KVO

© www.soinside.com 2019 - 2024. All rights reserved.