【问题标题】:Why are two different instances's isa pointer same?为什么两个不同实例的 isa 指针相同?
【发布时间】:2018-05-03 07:01:42
【问题描述】:

我想了很久。如果有人可以帮助我,我会很高兴。 我们知道每个实例对象都是一个结构体,它有一个 isa 指针。

typedef struct objc_object {
    Class isa;
} *id;

所以不同的实例应该有不同的isa。但事实恰恰相反。例如:

@interface Foo : NSObject
@property(nonatomic, strong) NSString *name;    
@end

然后

    Foo *foo1 = [[Foo alloc] init];
    foo1.name = @"foo1";

    Foo *foo2 = [[Foo alloc] init];
    foo2.name = @"foo2";

    NSLog(@"foo1->isa--%p", [foo1 class]);
    NSLog(@"foo2->isa--%p", [foo2 class]);

结果:

foo1->isa--0x10ed00df0
foo2->isa--0x10ed00df0

两个isa是一样的!为什么它们是一样的?但是 foo1 与 foo2 不同! foo1.name 和 foo2.name 存储在哪里? foo1 和 foo2 的属性是否存储在一个表中,其键为“foo1”或“foo2”,值为属性列表?

【问题讨论】:

  • 因为它们属于同一类。 foo1“是”Foofoo2 也是。 0x10ed00df0 指向 Foo 类。
  • 我知道,所以 foo1 和 foo2 的所有属性都存储在同一个 isa 中?
  • @Park isa 指针是一个位于对象结构开头的指针,它告诉您该对象是什么类。类的特定成员在内存中的isa 指针之后 ——事实上,id 并没有捕获结构的完整大小;它只是指向一个对象的开头(类似于数组如何衰减为 C 中的指针:C 中的数组指针只是指向内存中数组的开头)。
  • 具有相同类的两个事物具有相同的isa指针,因为class对象是相同的。您要比较的不是foo1->isafoo2->isa,而是foo1foo2,它们是指向对象本身的指针。这些指针是不同的。
  • @ItaiFerber 非常感谢!你帮我 ! ivars 在 isa 指针之后,因为指针是 8 个字节,所以第一个 ivar 从 8 个字节开始。

标签: objective-c runtime


【解决方案1】:

isa 指针(读取:是一个)指向该对象的类型信息,而不是它的状态(又名所有 ivars 的值的集合)。因此对于同一个类的两个对象(包括类对象),isa指向同一个类型信息(类)。此类型信息是类型的通用描述(包括哪些方法,存在哪些 ivars),而不是实际值(也称为状态)。

状态是——为了简化更复杂的事情——存储在 isa 的“后面”:

instance i in memory
i+00 isa pointer           // points to the type, equal for all instances of a class
i+04 value of the 1st ivar // different for every instance
i+08 value of the 2nd ivar // "
…

因此,当从系统获取实例的内存时,它不仅是 objc_object 结构的内存,还包括 ivars。

你可以想象这样的事情:

struct objc_object   struct myClass_instance
{                    {
  Class isa;           Class isa;
                       id my1stIVar;
                       id my2ndIVar;
                       …
}                    }

请注意,几年来实际的内存布局是不同的。不过,这个例子足以回答你的问题了。

【讨论】:

  • 非常感谢!我知道了!我搜索了很多文章和文档来寻找答案,但大多数人都在谈论 class、metaclass、methodList、ivarList 等。只有你回答才是我想要的,而且很清楚!真正的 ivars 落后于 isa。有力的证据是“ivar_getOffset(ivar)”方法返回8,而isa指针的大小只有8!我很高兴!
  • 不客气。请随意投票和/或检查我的答案。
猜你喜欢
  • 2012-07-21
  • 2021-04-17
  • 1970-01-01
  • 2019-09-14
  • 2020-05-03
  • 2018-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多