如何摆脱等待完成处理程序
How to get rid of waiting for Completion Handler
我在用户单击按钮时加载内容,等待下载并向用户显示内容。
我使用 URLSession.shared.dataTask
和 return 作为 (completion: @escaping closure (_ data: Data?) -> Void)
的响应
但是,如果用户想在内容加载前离开控制器,那么 self.navigationController?.popViewController (animated: true)
该控制器保留在内存中(deinit{}
不要调用)。据我了解,这是因为控制器正在等待 Completion Handler 回调。
我应该使用什么以及如何使用以便当用户关闭此视图控制器时,他将从内存中删除,而不是永远留在那里(直到用户终止应用程序)?
你说:
As I understand it, this is because the controller is expecting a Completion Handler callback.
如果视图控制器没有被释放,那是因为对它有挥之不去的强引用。在您的情况下,听起来您的闭包保留了强烈的参考。为了避免保留强引用,您可以在闭包中使用 [weak self]
捕获列表,例如
let task = URLSession.shared.dataTask(with: url) { [weak self] data, response, error in // note `[weak self]` capture list
guard let self = self else { return } // safely unwrap the optional
... // the rest of this like before
}
task.resume()
如果您想更进一步,您也可以在离开时取消任务,例如
private weak var savedTask: URLSessionTask?
deinit {
savedTask?.cancel() // cancel if if it hasn't finished already
}
func foo() {
...
let task = URLSession.shared.dataTask(with: url) { [weak self] data, response, error in // note `[weak self]` capture list
guard let self = self else { return } // safely unwrap the optional
... // the rest of this like before
}
task.resume()
savedTask = task
}
这样,如果网络请求的唯一目的是更新 UI,我们可以在不再需要请求的数据时释放网络资源。
所有这些都假定这是您拥有的唯一挥之不去的强引用(即,您看到 deinit
在网络请求完成时被调用)。如果不是,请确保 all 异步闭包使用弱引用并且您没有任何强引用循环。问题的常见来源是重复计时器、观察者等,或传统的强引用循环。 (您可以使用“调试内存图”功能找出这些强引用的位置,如 中所述。)
我在用户单击按钮时加载内容,等待下载并向用户显示内容。
我使用 URLSession.shared.dataTask
和 return 作为 (completion: @escaping closure (_ data: Data?) -> Void)
但是,如果用户想在内容加载前离开控制器,那么 self.navigationController?.popViewController (animated: true)
该控制器保留在内存中(deinit{}
不要调用)。据我了解,这是因为控制器正在等待 Completion Handler 回调。
我应该使用什么以及如何使用以便当用户关闭此视图控制器时,他将从内存中删除,而不是永远留在那里(直到用户终止应用程序)?
你说:
As I understand it, this is because the controller is expecting a Completion Handler callback.
如果视图控制器没有被释放,那是因为对它有挥之不去的强引用。在您的情况下,听起来您的闭包保留了强烈的参考。为了避免保留强引用,您可以在闭包中使用 [weak self]
捕获列表,例如
let task = URLSession.shared.dataTask(with: url) { [weak self] data, response, error in // note `[weak self]` capture list
guard let self = self else { return } // safely unwrap the optional
... // the rest of this like before
}
task.resume()
如果您想更进一步,您也可以在离开时取消任务,例如
private weak var savedTask: URLSessionTask?
deinit {
savedTask?.cancel() // cancel if if it hasn't finished already
}
func foo() {
...
let task = URLSession.shared.dataTask(with: url) { [weak self] data, response, error in // note `[weak self]` capture list
guard let self = self else { return } // safely unwrap the optional
... // the rest of this like before
}
task.resume()
savedTask = task
}
这样,如果网络请求的唯一目的是更新 UI,我们可以在不再需要请求的数据时释放网络资源。
所有这些都假定这是您拥有的唯一挥之不去的强引用(即,您看到 deinit
在网络请求完成时被调用)。如果不是,请确保 all 异步闭包使用弱引用并且您没有任何强引用循环。问题的常见来源是重复计时器、观察者等,或传统的强引用循环。 (您可以使用“调试内存图”功能找出这些强引用的位置,如