Desgard_Duan Desgard_Duan - 2 months ago 8
Objective-C Question

Does `isa` pointer carry other message about an instantiation in Objective-C?

I always think the

isa
pointer points to the Class of the instantiation. And the Class's
isa
pointer points to the its
metaclass
.
But in some article about the introduction of
isa
pointer, the author wrote: every bits in
isa
pointer can carry some message about the object. This like following:

[objc explain]: Non-pointer isa

从 NSObject 的初始化了解 isa

1 bit indexed 0 is raw isa, 1 is non-pointer isa.
1 bit has_assoc Object has or once had an associated reference. Object with no associated references can deallocate faster.
1 bit has_cxx_dtor Object has a C++ or ARC destructor. Objects with no destructor can deallocate faster.
30 bits shiftcls Class pointer's non-zero bits.
9 bits magic Equals 0xd2. Used by the debugger to distinguish real objects from uninitialized junk.
1 bit weakly_referenced Object is or once was pointed to by an ARC weak variable. Objects not weakly referenced can deallocate faster.
1 bit deallocating Object is currently deallocating.
1 bit has_sidetable_rc Object's retain count is too large to store inline.
19 bits extra_rc


But in my test, I found the low three bits were always 0, it just like:

enter image description here

And I had added the associated object in
NSObject
, but the second bit (
has_assoc
) is not 1 in
isa
pointer.

So how can I understand the
isa
pointer?

Answer

Setting an associated object to a value of nil is a no-op, and will not be added to the associated objects side-table. Thus, it's isa tag does not change.

See the following example, to show that the tag bits do work:

NSObject *object = [NSObject new];

NSLog(@"isa: %p ", *(void **)(__bridge void *)object);

static void *someKey = &someKey;
objc_setAssociatedObject(object, someKey, nil, OBJC_ASSOCIATION_RETAIN);

NSLog(@"isa: %p ", *(void **)(__bridge void *)object);

For me, on OSX 10.11 outputs:

2016-09-22 14:37:20.132 TestProj[95942:1117770] isa: 0x1dffff757a50f1 
2016-09-22 14:37:24.208 TestProj[95942:1117770] isa: 0x1dffff757a50f1 

But if I change the value from nil to an actual pointer value:

objc_setAssociatedObject(object, someKey, @"Hello World!", OBJC_ASSOCIATION_RETAIN);

I get the (expected) output, which includes the tagged bits being set in the pointer:

2016-09-22 14:40:24.190 TestProj[96095:1121411] isa: 0x1dffff757a50f1 
2016-09-22 14:40:24.191 TestProj[96095:1121411] isa: 0x1dffff757a50f3 
Comments