我们不确切知道数据是如何存储的,但我们可以排除几个选项:
私有实现变量
我们可以排除这种情况,仅仅是因为当我们遍历NSObject
类的 iVar 时,我们只看到一个: isa
,如通过该程序所示:
id object = [NSObject new];
Class meta = object->isa;
printf("class name: %s\n", class_getName(meta));
unsigned count;
Ivar *ivars = class_copyIvarList(meta, &count);
for (int i = 0; i < count; i++) {
printf("iVar: %s\n", ivar_getName(ivars[i]));
}
free(ivars);
请注意,甚至私有实现属性也存在于类元数据中。
私人财产
我们也可以排除这种情况,因为在类元数据中甚至公开了私有属性,如下例所示,NSObject
该类没有属性:
id object = [NSObject new];
Class meta = object->isa;
printf("class name: %s\n", class_getName(meta));
objc_property_t *properties = class_copyPropertyList(meta, &count);
for (int i = 0; i < count; i++) {
printf("property: %s\n", property_getName(properties[i]));
}
关联对象
这个很难排除,因为没有直接的方法来获取所有关联对象的列表。但是,由于关联对象的概念非常新,并且引用计数一直存在,我说这不太可能。
CoreFoundation 结构修改
这是我最好的猜测。当您创建一个 NSObject 时,它是一个幕后结构。也就是说实际的 NSObject 数据表示是这样的:
typedef struct CFObject {
int retainCount;
id isa;
} *CFObjectRef;
然后,当创建一个对象时:
id object_createInstance(...)
{
CFObjectRef object = malloc(sizeof(struct CFObject));
...
return (id) (object + sizeof(object->retainCount));
}
int object_retainCount(id self)
{
CFObjectRef asObject = (CFObjectRef) (self - sizeof(asObject->retainCount));
return asObject->retainCount;
}
但是,我无法验证这一点,因为还有许多其他方法可以做到这一点(例如,整数到对象的映射)。