Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is isa field of Objective C object has 1 offset with its class pointer?

I'm trying to using the following code to understand NSObject's C struct layout. First I print its struct layout using NSData, then I print the class pointer directly using [NSObject class].

id obj = [NSObject new];
long nsSize = class_getInstanceSize([NSObject class]);
NSData *nsData = [NSData dataWithBytes:(__bridge const void *)obj length:nsSize];
NSLog(@"obj: %@", nsData);
NSLog(@"NSObject Class: %p", [NSObject class]);

And I got the result:

2015-10-15 08:11:53.913 ObjC_CMD[11406:1999149] obj: <f1e06573 ffff1d00>
2015-10-15 08:11:53.913 ObjC_CMD[11406:1999149] NSObject Class: 0x7fff7365e0f0

What's interesting is the end of class pointer is e0f0, while the NSData print result shows its isa as eof1 (it's in reverse order because of little endian). I read in book that the isa pointer is topmost in an object's struct layout, so why it has 1 offset?

By the way, I have also tried on other types of objects, there is always 1 offset between isa and class pointer. Shouldn't they be the same?

P.S. I just noticed that the class pointer begins with 0x7fff, but the isa in C struct seems to be 0xffff, this difference is also interesting. What's the exact relationship between isa field and class pointer obtained from [NSObject class]?

like image 915
Zhu Shengqi Avatar asked Oct 15 '15 00:10

Zhu Shengqi


1 Answers

The 1 in the least significant bit means isa is not a pointer. In 64-bit land, the 64-bits of isa got repurposed into a bit-mask. On the most significant side of the isa bit-mask are other bit fields and the reference count.

Part of the isa bit-mask (30 bits in the middle) identify the class object, which is the part you recognized.

like image 102
Jeffery Thomas Avatar answered Sep 22 '22 01:09

Jeffery Thomas