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) {
}];
注意,你要问问自己是否真的需要查询在视图控制器被释放后继续运行。如果不是,您可以将此请求设置为可取消,然后在视图被关闭后将其取消。但这完全是一个单独的话题。
这段代码有什么问题吗?
[[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) {
}];
注意,你要问问自己是否真的需要查询在视图控制器被释放后继续运行。如果不是,您可以将此请求设置为可取消,然后在视图被关闭后将其取消。但这完全是一个单独的话题。