Maybe,there have two points that you should know.
First,in most cases,pass a nil value to a dictionary cause to remove the key form the dictionary.
Such as - (void)setObject:(ObjectType)object forKeyedSubscript:(id<NSCopying>)aKey and void objc_setAssociatedObject(id object, void *key, id value, objc_AssociationPolicy policy).
NSMutableDictionary *dic = [NSMutableDictionary dictionary]; dic[@"name"] = @"酷酷的哀殿"; dic[@"name"] = nil; NSLog(@"%@", dic);// it's output is `{}`.
Second,you should know the byte-order of your target device.
You can test it by follow code.
int msg = 0x01020304; char *buffer = (char *)&msg; printf("%d %d %d %d\n", buffer[0], buffer[1], buffer[2], buffer[3]);
In my x86-64 device,it's output is 4 3 2 1.
So,when I change has_assoc,the last but one byte will have a change.
And in pointer,it will add/minus 2.
isa: 0x1dffff795ca0f1 isa: 0x1dffff795ca0f3
For isa_t,you can use follow code to get has_assoc.
#import <Foundation/Foundation.h> #import <objc/runtime.h> int main() { // extra_rc must be the MSB-most field (so it matches carry/overflow flags) // indexed must be the LSB (fixme or get rid of it) // shiftcls must occupy the same bits that a real class pointer would // bits + RC_ONE is equivalent to extra_rc + 1 // RC_HALF is the high bit of extra_rc (i.e. half of its range) // future expansion: // uintptr_t fast_rr : 1; // no r/r overrides // uintptr_t lock : 2; // lock for atomic property, @synch // uintptr_t extraBytes : 1; // allocated with extra bytes # if __arm64__ # define ISA_MASK 0x0000000ffffffff8ULL # define ISA_MAGIC_MASK 0x000003f000000001ULL # define ISA_MAGIC_VALUE 0x000001a000000001ULL struct isa_t { uintptr_t indexed : 1; uintptr_t has_assoc : 1; uintptr_t has_cxx_dtor : 1; uintptr_t shiftcls : 33; // MACH_VM_MAX_ADDRESS 0x1000000000 uintptr_t magic : 6; uintptr_t weakly_referenced : 1; uintptr_t deallocating : 1; uintptr_t has_sidetable_rc : 1; uintptr_t extra_rc : 19; # define RC_ONE (1ULL<<45) # define RC_HALF (1ULL<<18) }; NSLog(@"arm64"); static void *someKey = &someKey; id object = [NSObject new]; struct isa_t *isa = (__bridge struct isa_t *)object; NSLog(@"%d", isa->has_assoc); objc_setAssociatedObject(object, someKey, @"Hello World!", OBJC_ASSOCIATION_RETAIN); NSLog(@"%d", isa->has_assoc); NSLog(@"%p", *(void * *)(__bridge void *)object); # elif __x86_64__ # define ISA_MASK 0x00007ffffffffff8ULL # define ISA_MAGIC_MASK 0x001f800000000001ULL # define ISA_MAGIC_VALUE 0x001d800000000001ULL struct isa_t { uintptr_t indexed : 1; uintptr_t has_assoc : 1; uintptr_t has_cxx_dtor : 1; uintptr_t shiftcls : 44; // MACH_VM_MAX_ADDRESS 0x7fffffe00000 uintptr_t magic : 6; uintptr_t weakly_referenced : 1; uintptr_t deallocating : 1; uintptr_t has_sidetable_rc : 1; uintptr_t extra_rc : 8; # define RC_ONE (1ULL<<56) # define RC_HALF (1ULL<<7) }; NSLog(@"x86_64"); static void *someKey = &someKey; id object = [NSObject new]; struct isa_t *isa = (__bridge struct isa_t *)object; NSLog(@"%d", isa->has_assoc); objc_setAssociatedObject(object, someKey, @"Hello World!", OBJC_ASSOCIATION_RETAIN); NSLog(@"%d", isa->has_assoc); NSLog(@"%p", *(void * *)(__bridge void *)object); # else // Available bits in isa field are architecture-specific. # error unknown architecture # endif return 0; }