避免循环引用的坑:在Block中使用私有成员变量

大家都知道,在block中使用self经常会造成循环引用。通常解决办法就是使用__weak关键字先生成一个弱引用,然后再在block中使用:

// 清单1
__weak typeof(self) wself = self;
self.demoBlock = ^{
   [wself.tableView reloadData];
};

但是在block中直接使用类的私有成员变量也会造成循环引用:
例如ViewController中有一个block类型的成员属性someBlock,另外一个是私有变量_children:

// 清单2
@interface ViewController : UIViewController
{
     NSMutableArray *_children;
}
@property (copy, nonatomic) void(^someBlock)();

其实在默认情况下,ViewController中的_children是使用__strong修饰的,清单2就等价于下面的清单3

// 清单3
@interface ViewController : UIViewController
{
     __strong NSMutableArray *_children;
}
@property (copy, nonatomic) void(^someBlock)();

这个时候,在为someBlock赋值的时候,直接使用__children 就会造成retain cycle:

// 清单4
- (void)viewDidLoad
{
  [super viewDidLoad];
  self.someBlock = ^{
    [_children addObject:@"Tom"];
    // 上面代码就等价于下面一行
    // [self->_children addObject:@"Tom"];
  };
}

要打破此循环引用,也要用到清单1中使用的方法,不同的是,必须在block内使用__strong的self:

 // 清单5
- (void)viewDidLoad
{
  [super viewDidLoad];
  __weak typeof(self) wself = self;
  self.someBlock = ^{
    __strong typeof(wself) sself = wself;
    [sself->_children addObject:@"Tom"];
  };
}

你可能感兴趣的:(避免循环引用的坑:在Block中使用私有成员变量)