block在iOS開發中被視作是對象,因此其生命周期會一直等到持有者的生命周期結束了才會結束。另一方面,由于block捕獲變量的機制,使得持有block的對象也可能被block持有,從而形成循環引用,導致兩者都不能被釋放:
@implementation LXDObject
{
void (^_cycleReferenceBlock)(void);
}
- (void)viewDidLoad
{
[super viewDidLoad];
_cycleReferenceBlock = ^{
NSLog(@"%@", self);? //引發循環引用
};
}
@end
遇到這種代碼編譯器只會告訴你存在警告,很多時候我們都是忽略警告的,這最后會導致內存泄露,兩者都無法釋放。跟普通變量存在__block關鍵字一樣的,系統提供給我們__weak的關鍵字用來修飾對象變量,聲明這是一個弱引用的對象,從而解決了循環引用的問題
__weak typeof(*&self) weakSelf = self;
_cycleReferenceBlock = ^{
NSLog(@"%@", weakSelf);? //弱指針引用,不會造成循環引用
};
對于block這種有趣的特性,在唐巧的談談Objective-C block的實現有詳細介紹block的底層實現代碼,我在這里就不多說了