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

sol*_*eil 1 asynchronous memory-management uiviewcontroller ios objective-c-blocks

这段代码有什么问题吗?

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

}];
Run Code Online (Sandbox Code Playgroud)

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

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

success(dictionary);
Run Code Online (Sandbox Code Playgroud)

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

Rob*_*Rob 5

使用self此处将阻止视图控制器在网络请求完成之前被释放.这里没有什么可以暗示你需要在这种情况下这样做,所以self这里的使用似乎不合适.我们可以构建您可能需要保留视图控制器的场景(但场景也表明存在一定程度的代码异味).

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

但是,您不需要使用weakSelf/ strongSelfpattern.如果需要确保如果指针不是nil在块启动时,则使用它nil,在块执行期间不会成为指针.这不适用于这个例子.

所以,这意味着你可能会有类似的东西:

typeof(self) __weak weakSelf = self;

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

}];
Run Code Online (Sandbox Code Playgroud)

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