Rob*_*ins 39 objective-c uiviewcontroller ios objective-c-blocks retain-cycle
假设我在UIViewController子类中有以下方法:
- (void)makeAsyncNetworkCall
{
[self.networkService performAsyncNetworkCallWithCompletion:^{
dispatch_async(dispatch_get_main_queue(), ^{
[self.activityIndicatorView stopAnimating];
}
});
}];
}
Run Code Online (Sandbox Code Playgroud)
我知道self块内部的引用导致UIViewController实例被块保留.只要performAsyncNetworkCallWithCompletion不将块存储在我的属性(或ivar)中NetworkService,我是否认为没有保留周期?
我意识到上面的这个结构将导致UIViewController被保留直到performAsyncNetworkCallWithCompletion完成,即使它是由系统早先发布的.但它可能(甚至可能吗?),系统会收回我的UIViewController 所有(更改到iOS 6的一个管理方式后UIViewController的后盾CALayer内存)?
如果有理由我必须做"弱自我/强自我舞蹈",它看起来像这样:
- (void)makeAsyncNetworkCall
{
__weak typeof(self) weakSelf = self;
[self.networkService performAsyncNetworkCallWithCompletion:^{
typeof(weakSelf) strongSelf = weakSelf;
if (!strongSelf) {
return;
}
dispatch_async(dispatch_get_main_queue(), ^{
[strongSelf.activityIndicatorView stopAnimating];
}
});
}];
}
Run Code Online (Sandbox Code Playgroud)
但是我觉得这很难看,并且如果没有必要就想避免它.
Rob*_*Rob 30
由于我相信您正确诊断,self在这种情况下使用不一定会导致强大的参考周期.但是这将在网络操作完成时保留视图控制器,在这种情况下(如在大多数情况下),没有必要.因此,可能没有必要使用weakSelf,但可能谨慎这样做.它最大限度地减少了意外强引用周期的可能性,并导致更有效地使用内存(一旦视图控制器被关闭就释放与视图控制器关联的内存,而不是在网络操作完成之后不必要地保留视图控制器) .
但是,不需要strongSelf构造.您可以:
- (void)makeAsyncNetworkCall
{
__weak typeof(self) weakSelf = self;
[self.networkService performAsyncNetworkCallWithCompletion:^{
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf.activityIndicatorView stopAnimating];
});
}];
}
Run Code Online (Sandbox Code Playgroud)
您只需要weakSelf/ strongSelf组合,这对于拥有强大的参考(例如,您正在解除引用ivars)或者您需要担心竞争条件至关重要.这似乎不是这种情况.
我认为问题在于networkService可能会对块进行强有力的引用.并且视图控制器可能具有对networkService的强引用.因此可能存在VC-> NetworkService-> block-> VC 的可能循环.但是,在这种情况下,通常可以安全地假设块在运行后将被释放,在这种情况下循环被破坏.因此,在这种情况下,没有必要.
必要时,如果块未被释放.比方说,你没有一个在网络调用后运行一次的块,而是有一个用作回调的块.即networkService对象维护对块的强引用,并将其用于所有回调.在这种情况下,块将具有对VC的强引用,这将创建一个强循环,因此首选弱引用.
| 归档时间: |
|
| 查看次数: |
9988 次 |
| 最近记录: |