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

时间:2015-01-19 22:54:52

标签: ios memory-management asynchronous uiviewcontroller objective-c-blocks

这段代码有什么问题吗?

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

}];

具体来说,如果在网络任务完成之前调用此方法的视图控制器被取消分配,会发生什么?弱自己,强自我需要吗?为什么或为什么不呢?

网络管理员只是进行网络调用,如果从服务器获取有效数据,则通过执行此操作将响应返回给调用视图控制器:

success(dictionary);

对我来说似乎很好,因为块本身并没有保留在任何地方,但我可能错了......

1 个答案:

答案 0 :(得分:5)

此处使用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) {

}];

注意,您必须问自己,在取消分配视图控制器后是否确实需要查询继续运行。如果没有,您可以取消此请求,然后在取消视图后取消它。但这完全是一个单独的话题。