ios - 在从 UIViewController 调用的非保留完成中引用 self 时,weakSelf/strongSelf 舞蹈真的有必要吗?

标签 ios objective-c uiviewcontroller objective-c-blocks retain-cycle

假设我在 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/

相关文章:

objective-c - 使用 [PFFFacebookUtils initializeFacebookWithApplicationLaunchOptions :launchOptions] (semaphore_wait_slow trap) 解析自 Facebook 4.0.x 以来的登录挂起

objective-c - 如何一次关闭 3 个模态视图 Controller ?

ios - 带委托(delegate)的 Swift 扩展 (UIViewController)

ios - 以编程方式显示和隐藏 View Controller

iOS 库或 DIY Etsy 之类的类别控制?

ios - Swift - 如果小数等于 0,如何从 float 中删除小数?

iphone - iOS 上的多页应用程序

ios - 从 json 数据值创建字典

ios - 如何在单元格 iOS 中为按钮设置标签?

objective-c - 将对象 ( UIViewController ) 转换到它们未知的子类