大家都知道,在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"];
};
}