假设我在 UIViewController
子类中有以下方法:
- (void)makeAsyncNetworkCall
{
[self.networkService performAsyncNetworkCallWithCompletion:^{
dispatch_async(dispatch_get_main_queue(), ^{
[self.activityIndicatorView stopAnimating];
}
});
}];
}
我知道 block 内对 self
的引用会导致 UIViewController
实例被 block 保留。只要 performAsyncNetworkCallWithCompletion
不将 block 存储在我的 NetworkService
上的属性(或 ivar)中,我认为没有保留周期是否正确?
我意识到上面的这个结构会导致 UIViewController 被保留到 performAsyncNetworkCallWithCompletion
完成,即使它是由系统提前释放的。但是有可能(甚至可能?)系统会释放我的 UIViewController
at all ( after the changes to the way iOS 6 manages a UIViewController
's backing CALayer
memory )?
如果有理由我必须跳“weakSelf/strongSelf dance”,它看起来像这样:
- (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];
}
});
}];
}
但我觉得这非常丑陋,如果没有必要,我想避免它。
最佳答案
我相信您的诊断正确,在这种情况下使用 self
不一定会导致强引用循环。但这将在网络操作完成时保留 View Controller ,在这种情况下(与大多数情况一样),没有必要这样做。因此,可能没有必要使用 weakSelf
,但这样做可能是谨慎的。它最大限度地减少了意外强引用循环的机会,并导致更有效地使用内存(一旦 View Controller 被解除,就释放与 View Controller 关联的内存,而不是在网络操作完成之前不必要地保留 View Controller ) .
不过,不需要 strongSelf
构造。你可以:
- (void)makeAsyncNetworkCall
{
__weak typeof(self) weakSelf = self;
[self.networkService performAsyncNetworkCallWithCompletion:^{
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf.activityIndicatorView stopAnimating];
});
}];
}
您只需要 weakSelf
/strongSelf
组合,其中有一个强引用至关重要(例如,您正在取消引用 ivars)或者如果您需要担心种族条件。此处似乎并非如此。
关于ios - 在从 UIViewController 调用的非保留完成中引用 self 时,weakSelf/strongSelf 舞蹈真的有必要吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21113963/