swift - 使用内部闭包时可能存在内存泄漏
问题描述
我想确保以下内容没有内存泄漏。现在,为了在使用网络调用时从我的代码中抛出错误以使其正常工作,我必须保留对我dispatchgroup
和function
处理数据的引用。
func myFunc(
completion: @escaping (_ success: () throws -> Bool) -> Void) {
let fG = DispatchGroup()
let processLinks = self.processDownloadData
requestDownloadLinks(fromURL: url) { result in
switch result {
case .success(let data):
processLinks(data, fG, stagingBundle, {_ in
switch result {
case .failure(let error):
completion({ throw error })
case .success:
completion({ return true })
}
})
case .failure(let error):
completion({ return true })
}
}
在哪里processDownloadData
func processDownloadData(
data: ((urls: [(url: URL, language: String)], version: String)),
dispatchGroup: DispatchGroup),
completion: @escaping (_ success: () throws -> Bool) -> Void) {
//write data
}
和requestDownloadLinks
final func requestDownloadLinks(
fromURL url: URL,
completion: ((Result<(urls: [(url: URL, language: String)],
version: String), Error>) -> Void)? = nil
) {
DispatchQueue.global(qos: .background).async { [weak self] in
guard let self = self else {return}
self.httpManager?.get(url: url) {result in
switch result {
case .failure(let error):
if let completion = completion {
completion(.failure(LokalisationError.network(originatingError: error)))
}
case .success(let data):
do {
guard let data = data as? Data else {
if let completion = completion {
completion(.failure(LokalisationError.malformedDataFromServer))
}
return
}
let decoder = JSONDecoder()
let contents = try decoder.decode(EndPointResponse.self, from: data)
if let data = contents.data {
let urls = data.map { URL(string: $0.url) ?? URL(fileURLWithPath: "") }
let language = data.map { $0.language }
let urlsForLang = Array(zip(urls, language))
if let completion = completion {
completion(.success( (urlsForLang, contents.version) ))
}
}
} catch let error {
if let completion = completion {
completion(.failure(LokalisationError.network(originatingError: error)))
}
}
}
}
}
}
现在通过这样做我会造成内存泄漏吗?当我创建对dispatchgroup
和函数的引用时,我认为在 http 调用完成之前它们不会被释放。现在这没关系,因为它要么成功完成,要么出错。还是这会导致内存泄漏?
解决方案
您的 DispatchGroup 将一直completion()
存在,直到完成为止,requestDownloadLinks
除非您在其中做一些有趣的processDownloadData
事情。您通过一个闭包块将它作为来自myFunc()
to的引用传递,在requestDownloadLinks
该闭包块中您调用processDownloadData
将 DispatchGroup 传递给它。如果它没有被传递或作为参考保存在其中,那么您可能是安全的。确保使用 Instruments 分析您的应用程序并检查内存分配和僵尸。您还可以在调试器中检查内存占用。如果您多次调用 myfunc,您应该会看到内存稳步增加。
推荐阅读
- python - 我如何只训练新的重量?
- html - 如何在 Angular JS 中通过 URL 调用 JSON 数据
- actions-on-google - 对 Google 的操作有效,但 Dialogflow 代理已损坏
- swift - Swift - WKWebView 和 itms-services(又名打开弹出窗口)
- python - 使用三元 if 语句条件在两个变量之间应用
- php - 每次在 Laravel 中更改状态时发送 Slack 通知
- windows - 如何在启动时自动获取 Windows 机器的公共 IP 并将其发送给我(例如通过电子邮件)
- wordpress - WooCommerce 3.3:覆盖默认图像大小“shop_thumbnail”
- angular - prime-ng 为角度 4 中数据表之外的列字段集创建自定义过滤器
- json - 如何使用 jq 按日期时间字段排序?