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

查看:119
本文介绍了当从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 $ c> 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 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)?

如果有理由我必须做弱自我/强自我舞,它看起来像这样:

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天全站免登陆