iOS - 使用成功块进行异步网络调用时查看控制器内存管理

iOS - View Controller memory management when doing async networking calls with success block

这段代码有什么问题吗?

[[MyNetworkManager shared] getSomeData:param success:^(NSDictionary *response) { 
    self.view.backgroundColor = [UIColor redColor];
} failure:^(NSString *errorString) {

}];

具体来说,如果调用此方法的视图控制器在网络任务完成之前被释放,会发生什么情况?这里需要weakSelf, strongSelf吗?为什么或为什么不?

网络管理器只是进行网络调用,如果从服务器获取有效数据,则returns通过这样做对调用视图控制器的响应:

success(dictionary);

我觉得没问题,因为块本身没有保留在任何地方,但我可能是错的...

此处使用 self 将阻止视图控制器在网络请求完成之前被释放。这里没有任何内容建议您在这种情况下需要这样做,因此在这里使用 self 似乎不合适。我们可以构建您可能需要保留视图控制器的场景(但这些场景也暗示了一定程度的代码味道)。

你可以在这里使用 weakSelf 模式,这不会在视图控制器上保持强引用。因此,如果视图控制器在网络请求完成之前被解除,它将被释放并且 weakSelf 指针将为 nil。这似乎是一种合乎逻辑的方法。

不过,您不需要使用 weakSelf/strongSelf 模式。如果您需要确保如果指针在块开始时不是 nil,则在块执行期间它不会变为 nil,则可以使用它。这不适用于此示例。

所以,这意味着您可能会遇到类似的情况:

typeof(self) __weak weakSelf = self;

[[MyNetworkManager shared] getSomeData:param success:^(NSDictionary *response) { 
    weakSelf.view.backgroundColor = [UIColor redColor];
} failure:^(NSString *errorString) {

}];

注意,你要问问自己是否真的需要查询在视图控制器被释放后继续运行。如果不是,您可以将此请求设置为可取消,然后在视图被关闭后将其取消。但这完全是一个单独的话题。