Desgard_Duan Desgard_Duan - 3 months ago 10
Objective-C Question

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

I always think the

pointer points to the Class of the instantiation. And the Class's
pointer points to the its
But in some article about the introduction of
pointer, the author wrote: every bits in
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
, but the second bit (
) is not 1 in

So how can I understand the


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