oc block 中直接引用成员变量 循环引用

来源:互联网 发布:java的wait方法 编辑:程序博客网 时间:2024/05/21 09:58

问题的答案是一定会发生循环引用。


那解决方式:

 __weak typeof(self) wself = self;
用wself访问成员变量就好。


既然发生了循环引用一定是retain了self了,那又是为什么block不retain成员变量指针会retain self 呢?


原因是oc是动态语言,实例变量的地址可能被其他实例变量占用,直接引用的话容易出问题。


retain self的好处是当类的定义变了,其存储的偏移量也变了,偏移量会在运行时查找,这样的话无论何时访问总能得到正确的地址,甚至可以在运行时新增变量。


  1. struct objc_class {  
  2.     Class isa  OBJC_ISA_AVAILABILITY;  
  3.   
  4. #if !__OBJC2__  
  5.     Class super_class                                        OBJC2_UNAVAILABLE;  
  6.     const charchar *name                                         OBJC2_UNAVAILABLE;  
  7.     long version                                             OBJC2_UNAVAILABLE;  
  8.     long info                                                OBJC2_UNAVAILABLE;  
  9.     long instance_size                                       OBJC2_UNAVAILABLE;  
  10.     struct objc_ivar_list *ivars                             OBJC2_UNAVAILABLE;  
  11.     struct objc_method_list **methodLists                    OBJC2_UNAVAILABLE;  
  12.     struct objc_cache *cache                                 OBJC2_UNAVAILABLE;  
  13.     struct objc_protocol_list *protocols                     OBJC2_UNAVAILABLE;  
  14. #endif  
  15.   
  16. } OBJC2_UNAVAILABLE;  

其中objc_ivar_list结构体存储着objc_ivar数组列表,而objc_ivar结构体存储了类的单个成员变量的信息。


Ivar 在objc中被定义为:

[objc] view plain copy
  1. typedef struct objc_ivar *Ivar;  

它是一个指向objc_ivar结构体的指针,结构体有如下定义:

[objc] view plain copy
  1. struct objc_ivar {  
  2.     charchar *ivar_name                                          OBJC2_UNAVAILABLE;  
  3.     charchar *ivar_type                                          OBJC2_UNAVAILABLE;  
  4.     int ivar_offset                                          OBJC2_UNAVAILABLE;  
  5. #ifdef __LP64__  
  6.     int space                                                OBJC2_UNAVAILABLE;  
  7. #endif  
  8. }                                                            OBJC2_UNAVAILABLE;  

这里我们注意第三个成员 ivar_offset。它表示基地址偏移字节。


0 0