I always think the
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
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