Block循环引用

2016-10-17  本文已影响0人  14号孤独患者

循环引用

某个对象有一个copy或者strong成员变量或者属性,这时block内部直接引用了成员变量或者self,这样就产生了self持有block成员,block成员持有self,就会导致循环引用。因为self本身就是一个strong类型的变量。苹果官方的建议是:传进block之前,把self转换成weak automatic的变量,这样在block中就不会出现对self的强引用。如果在block执行完成之前,self被释放,weakSelf也会置为nil。weak类型相对比较安全,因为可以在释放后自动置为nil,不会引起野指针。

weakSelf声明

  1. __weak typeof(self) weakSelf = self;
    这句话的意思是声明了一个self类型的weak指针,名字叫做weakSelf. typeof是用来求参数类型的,这里也就是来求self的类型。这样定义出的weakSelf就是和self是一个类型,并且是原self的一个弱引用。
  2. __weak typeof(&*self) weakSelf = self;
  3. __weak MyViewController *weakSelf = self;

代码演示

  1. 声明几个block和一个属性:
    @interface ViewController (){ void(^myBlock1)(void);//该block参数为void,返回值为void void(^myBlock2)(void); void(^myBlock3)(void); } @property (nonatomic,copy) NSString *person; @end
  2. 使用weakSelf不会引起循环引用:
 NSLog(@"init-->value:%@,address=%p,self=%p",self.person,self.person,self);
myBlock1 = ^(void){
    //这样不会造成循环引用
 NSLog(@"execute1-->value:%@,address=%p,weakSelf=%p",weakSelf.person,weakSelf.person,weakSelf);
};```
3. 直接使用self,会循环引用:Xcode会给警告
```myBlock2 = ^(void){
    //这样造成循环引用
    NSLog(@"execute2--> value:%@,address=%p,self=%p",self.person,self.person,self);
};```
4. 要执行的方法抽取出来,也不会循环引用:

myBlock3 = ^(void){
//这样也不会造成循环引用,已经抽取出要执行的方法
[weakSelf myBlock3Func];
};```

    NSLog(@"execute3--> value:%@,address=%p,self=%p",self.person,self.person,self);
}
  1. block不是self的属性或者变量时,在block内使用self也不会循环引用:
    //block不是self的属性时,block内部使用self也不是循环引用
Animal *animal = [[Animal alloc] init];
animal.animalBlock = ^(void){ 
NSLog(@"animal-value:%@,address=%p,self=%p",self.person,self.person,self);
};```
6. block的调用如下:
```myBlock1();
myBlock2();
myBlock3();
animal.animalBlock();```
上一篇下一篇

猜你喜欢

热点阅读