在从 UIViewController 调用的非保留完成中引用 self 时,weakSelf/strongSelf 舞蹈真的有必要吗? [英] Is the weakSelf/strongSelf dance really necessary when referencing self inside a non-retained completion called from a UIViewController?

查看:16
本文介绍了在从 UIViewController 调用的非保留完成中引用 self 时,weakSelf/strongSelf 舞蹈真的有必要吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我在 UIViewController 子类中有以下方法:

Say I have the following method inside a UIViewController subclass:

- (void)makeAsyncNetworkCall
{
    [self.networkService performAsyncNetworkCallWithCompletion:^{
        dispatch_async(dispatch_get_main_queue(), ^{
                [self.activityIndicatorView stopAnimating];
            }
        });
    }];
}

我知道块内对 self 的引用会导致 UIViewController 实例被块保留.只要 performAsyncNetworkCallWithCompletion 不将块存储在我的 NetworkService 上的属性(或 ivar)中,我是否认为没有保留周期?

I know that the reference to self inside the block results in the UIViewController instance being retained by the block. As long as performAsyncNetworkCallWithCompletion does not store the block in a property (or ivar) on my NetworkService, am I right in thinking there is no retain cycle?

我意识到上面的这个结构会导致 UIViewController 被保留直到 performAsyncNetworkCallWithCompletion 完成,即使它被系统提前释放.但是它有可能(甚至可能吗?)系统会取消分配我的 UIViewController (在 iOS 6 管理UIViewController 的支持 CALayer 内存)?

I realise this structure above will lead to the UIViewController being retained until performAsyncNetworkCallWithCompletion finishes, even if it is released by the system earlier. But is it likely (or even possible?) the system will deallocate my UIViewController at all (after the changes to the way iOS 6 manages a UIViewController's backing CALayer memory)?

如果有什么原因我必须跳weakSelf/strongSelf 舞蹈",它看起来像这样:

If there is a reason I must do the "weakSelf/strongSelf dance", it would look like this:

- (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];
            }
        });
    }];
}

但我觉得这不合情理地丑陋,如果没有必要,我想避免它.

But I find this unconscionably ugly and would like to avoid it if it's not necessary.

推荐答案

我相信你的诊断是正确的,在这种情况下使用 self 不一定会导致强引用循环.但这将在网络操作完成时保留视图控制器,在这种情况下(在大多数情况下),没有必要.因此,可能没有必要使用 weakSelf,但这样做可能是谨慎的.它最大限度地减少了意外强引用循环的机会,并导致更有效地使用内存(在视图控制器被解除后立即释放与视图控制器关联的内存,而不是在网络操作完成之前不必要地保留视图控制器).

As I believe you correctly diagnosed, using self will not necessarily cause strong reference cycle in this scenario. But this will retain the view controller while the network operation completes, and in this case (as in most cases), there's no need to. Thus, it may not be necessary to do use weakSelf, but probably prudent to do so. It minimizes the chance of an accidental strong reference cycle and leads to more efficient use of memory (releasing the memory associated with the view controller as soon as that view controller is dismissed rather than unnecessarily retaining the view controller until after the network operation is complete).

虽然不需要 strongSelf 结构.您可以:

There is no need for the strongSelf construct, though. You can:

- (void)makeAsyncNetworkCall
{
    __weak typeof(self) weakSelf = self;
    [self.networkService performAsyncNetworkCallWithCompletion:^{
        dispatch_async(dispatch_get_main_queue(), ^{
            [weakSelf.activityIndicatorView stopAnimating];
        });
    }];
}

您只需要 weakSelf/strongSelf 组合,在这种情况下,强引用至关重要(例如,您正在取消引用 ivars)或者您需要担心种族条件.此处似乎并非如此.

You only need the weakSelf/strongSelf combination where it's critical to have a strong reference (e.g., you're dereferencing ivars) or if you need to worry about race conditions. That does not appear to be the case here.

这篇关于在从 UIViewController 调用的非保留完成中引用 self 时,weakSelf/strongSelf 舞蹈真的有必要吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆