情況分析
情況一:block是控制器的屬性池颈,如果block內部沒有使用weakSelf將會造成內存泄露
self.testBlock = ^(){
NSLog(@"%@",self.mapView);
};
self.testBlock();
情況二:把block內部抽出一個作為self的方法尾序,當使用weakSelf調用這個方法,并且這個方法里有self的屬性饶辙,block不會造成內存泄露
self.testBlock = ^(){
[weakSelf test];
};
-(void)test
{
NSLog(@"%@",self.mapView);
}
情況三:當block不是self的屬性時蹲诀,block內部使用self也不會造成內存泄露
TestBlock testBlock = ^(){
NSLog(@"%@",self.mapView);
};
[self test:testBlock];
情況四:當使用類方法有block作為參數(shù)使用時,block內部使用self也不會造成內存泄露
[WDNetwork testBlock:^(id responsObject) {
NSLog(@"%@",self.mapView);
}];
情況五:使用系統(tǒng)的某些block api(如UIView的block版本寫動畫時)弃揽,是否也考慮引用循環(huán)問題?
所謂“引用循環(huán)”是指雙向的強引用则北,所以那些“單向的強引用”(block 強引用 self )沒有問題矿微,比如這些:
[UIView animateWithDuration:duration animations:^{
[self.superview layoutIfNeeded];
}];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.someProperty = xyz;
}];
[[NSNotificationCenter defaultCenter] addObserverForName:@"someNotification"
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification * notification) {
self.someProperty = xyz;
}];
這些情況不需要考慮“引用循環(huán)”。
但如果你使用一些參數(shù)中可能含有 ivar 的系統(tǒng) api 尚揣,如 GCD 涌矢、NSNotificationCenter就要小心一點:比如GCD 內部如果引用了 self,而且 GCD 的其他參數(shù)是 ivar快骗,則要考慮到循環(huán)引用:
__weak __typeof__(self) weakSelf = self;
dispatch_group_async(_operationsGroup, _operationsQueue, ^
{
__typeof__(self) strongSelf = weakSelf;
[strongSelf doSomething];
[strongSelf doSomethingElse];
} );
類似的:
__weak __typeof__(self) weakSelf = self;
_observer = [[NSNotificationCenter defaultCenter] addObserverForName:@"testKey"
object:nil
queue:nil
usingBlock:^(NSNotification *note) {
__typeof__(self) strongSelf = weakSelf;
[strongSelf dismissModalViewControllerAnimated:YES];
}];
self --> _observer --> block --> self 顯然這也是一個循環(huán)引用娜庇。