ARC 环境下
1 什么是retain cycle
1) 1…n 个对象,都能构成 retain cycle
假设关系都是 strong
A.a=A 一个对象retain cycle
A.b=B B.a=A 两个对象购成的cycle
A.b=B B.c=C C.d=D D.a=A 四个对象购成的环
推而广之 1…n 个对象,都能构成 retain cycle
2)如何解开retain cycle
retain cycle是需要避免使用的,会造成理解的复杂性。但有时不得不使用。
环生成后,也可解开
A.a=A---->A.a=nil; A自动release了
A.b=B B.a=A----> A.b=nil(B release, A release) OR B.a=nil( A release, B release)
A.b=B B.c=C C.d=D D.a=A ----> 任设其中一个reference 为nil,整个环就断了,所有对象将release
3) retain cycle的生命期
retain cycle的生命期 依赖于 strong reference的生命期。
strong reference 的生命期就是该指针的生命期,如果 strong reference 是 object member, 那么 strong reference 的生命期就是 object 的生命期。(需要外界干涉破坏掉retain cycle)
strong reference 也可以是 是在stack里,如在函数内。函数return时,reference 不得存在,object retain count 自动-1, retain cycle也不复存在了。(retain cycle会自动破坏掉)
4)在我们使用三方library 或open source时,如何以最安全的方式使用block,即便我们对该block不了解。
很多三方open source 我们很难知道他们内部怎么使用了block, 内部retain cycle又是怎么建立的。因为retain cycle生成可能有n个对象参与其中, 我们怎么才能以最安全的方式使用block?
确保使用 strong reference 只存在 stack即执行期中。__unsafe_unretained 或weak在block的生命期中。
(void)configPullToRefresh{
__block __unsafe_unretained ICloud * tempSelf = self;
[self.dataTableView addPullToRefreshWithActionHandler:^{
__strong ICloud * strongSelf = tempSelf;
int64_t delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[strongSelf refresh];
});
}];
}
分析
1.程序运行期, 进入configPullToRefresh 函数。生成 refreshWithActionHandler block, block 创建,block内将有一个__unsafe_unretained的 tempSelf成员。破保了在block的生命期内不会形成retain cycle.
2.当用户下拉刷新时,block 内调,进入block的执行期, 执行期用了__strong TBSNSBasicView * strongSelf,将对 self 做一次retain, retain cycle出现了, 这时pop controller 也不会crashed,因为 block retain 了self 。block执行完,__strong TBSNSBasicView * strongSelf走到了尽头, retain cycle 自动消息, self 自动release
3. 能用weak最好,__unsafe_unretained有些局限,须开发知道在进入block执行期时,该object 没dealloc,否则将crashed.但在我们的环境中,如果用户pop controller后,我们是不能 trigger block 进入执行期的。
4.PLWeakCompatibility 提供了在5.0以前版本中 __weak的的适配可以了解能否在环境中使用。
https://github.com/plausiblelabs/PLWeakCompatibility