__weak
id obj = [[NSObject alloc] init];
@autoreleasepool {
id __weak obj1 = obj;
NSLog(@"%@",obj1);
}
括号内的代码编译器会转化为:
id obj1;
objc_initWeak(&obj1,obj);
id tmp = objc_loadWeakRetained(&obj1);
objc_autorelease(tmp);
NSLog(@"%@",tmp);
objc_destroyWeak(&obj1);
- 调用
objc_initWeak
存入sidetable
表 objc_loadWeakRetain
返回自身,并引用计数+1(refcnts
的value
+固定增量值
)objc_autorelease
加入自动释放池objc_destroyWeak
将weak
指针从weak_table_t
表中移除
那么sidetable
这个表是什么?
sidetable
并不是只有弱引用对象才有这个sidetable
,objc_object
对象拥有isa
指针,这个指针中存储了许多信息,其中几位就存储了引用计数,但是当引用计数大于无法使用位存储时,也会创建sidetable
,并使用sidetable
进行引用计数。同时objc_initWeak
也是创建sidetable
的。
这里贴出了isa
源码中arm64
位架构
# if __arm64__
# define ISA_MASK 0x0000000ffffffff8ULL
# define ISA_MAGIC_MASK 0x000003f000000001ULL
# define ISA_MAGIC_VALUE 0x000001a000000001ULL
struct {
uintptr_t nonpointer : 1;
uintptr_t has_assoc : 1; //有关联的对象
uintptr_t has_cxx_dtor : 1; //c++ 析构
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; //是否有sidetable引用计数
uintptr_t extra_rc : 19</