以下是该方案:
-A UIViewController(A)被推到导航堆栈上
- 在viewDidLoad上使用AFNetworking(整个应用程序共享的单例AFHTTPClient)调用异步GET,以填充视图上的各种用户元素(例如UILabel)。
- 用户在请求返回之前按下后退按钮
- 假设其他活动视图控制器可能正在发出请求,因此您无法取消所有打开的操作
问题#1是,你应该跟踪UIViewController A发出的打开请求,并在用户离开该视图时取消未完成的请求,还是应该让他们完成并忽略它们?由于AFNetworking使用块,因此更新的用户元素将保留在块内,因此在弹出视图后执行成功/失败块时不会导致崩溃。然而忽略它们的缺点似乎是不必要的网络流量。
问题#2,你在哪里执行代码取消UIViewController A的操作? viewDidDisappear似乎不对,因为用户可能已向前(将新视图推入堆栈)而不是返回(弹出当前视图),在这种情况下,您不希望取消打开的请求,因为用户可能会来回到当前视图,它将不会再次加载。但是,我不认为在请求执行时会调用dealloc或viewDidUnload,因为块将保留用户元素,所以我认为它不能去那里。
对此表示赞赏。您认为最佳做法是什么?
答案 0 :(得分:8)
一般来说,当用户离开视图控制器时,您实际上不需要取消请求。在内存管理方面,对块self的引用将防止因发送消息到解除分配的实例而导致的任何崩溃,因此不必担心。
就用户体验而言,我会说在问题出现之前你不应该真的担心它(我们的开发人员有一个诀窍,就是对我们的应用程序中的速度完全错误进行猜测)。但是,如果您正在进行大型GET请求,并且它会产生明显的迟缓,我的建议是让控制器在HTTPClient -cancelAllHTTPOperationsWithMethod:path:
中执行-viewDidUnload:
(任何其他回调都为时过早)。
答案 1 :(得分:0)
也许您可以拥有一个管理所有网络内容的单例,只需将其委托设置为当前的vc(在viewDidLoad中),这样您就可以获得任何传入数据,并在vc消失时向其发送取消消息(或者让一个不同的vc成为它的代表)。或者单例可以保留数据以供稍后阶段的任何vc访问。出于这个原因,我倾向于不将异步代码放入我的VC中。