问题的答案是一定会发生循环引用。
那解决方式:
__weak typeof(self) wself = self;
用wself访问成员变量就好。
既然发生了循环引用一定是retain了self了,那又是为什么block不retain成员变量指针会retain self 呢?
原因是oc是动态语言,实例变量的地址可能被其他实例变量占用,直接引用的话容易出问题。
retain self的好处是当类的定义变了,其存储的偏移量也变了,偏移量会在运行时查找,这样的话无论何时访问总能得到正确的地址,甚至可以在运行时新增变量。
- struct objc_class {
- Class isa OBJC_ISA_AVAILABILITY;
- #if !__OBJC2__
- Class super_class OBJC2_UNAVAILABLE;
- const charchar *name OBJC2_UNAVAILABLE;
- long version OBJC2_UNAVAILABLE;
- long info OBJC2_UNAVAILABLE;
- long instance_size OBJC2_UNAVAILABLE;
- struct objc_ivar_list *ivars OBJC2_UNAVAILABLE;
- struct objc_method_list **methodLists OBJC2_UNAVAILABLE;
- struct objc_cache *cache OBJC2_UNAVAILABLE;
- struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;
- #endif
- } OBJC2_UNAVAILABLE;
其中objc_ivar_list
结构体存储着objc_ivar
数组列表,而objc_ivar结构体存储了类的单个成员变量的信息。
Ivar
在objc中被定义为:
它是一个指向objc_ivar结构体的指针,结构体有如下定义:
这里我们注意第三个成员 ivar_offset
。它表示基地址偏移字节。