データがどのように保存されるかは正確にはわかりませんが、いくつかのオプションを除外することができます。
プライベート実装変数
このプログラムで示されているように、NSObject
クラスのiVarを反復処理すると、次の1つしか表示されないため、これを除外できます。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);
また、プライベート実装プロパティでさえ、クラスmetdataに存在することに注意してください。
プライベートプロパティ
次の例に示すように、プライベートプロパティでさえクラスのメタデータに公開されているため、これを除外することもできます。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;
}
ただし、これを行う方法は他にもたくさんあるため、これを確認することはできません(たとえば、整数のオブジェクトへのマップ)。