完成处理程序导致不调用 Deinit
Posted
技术标签:
【中文标题】完成处理程序导致不调用 Deinit【英文标题】:Completion Handler Causes Deinit To Not Be Called 【发布时间】:2019-04-29 20:15:30 【问题描述】:我有一个包含完成处理程序的网络任务,允许我确定任务是否以及何时成功完成;
func performUpload(url: URL, completionHandler: @escaping (_ response: Bool) -> ())
photoSave.savePhotoRemote(assetURL: url) response in
completionHandler(response)
我从另一个 UIView 调用这个函数,使用以下方法;
UploadHelper.shared.performUpload(url: fileAssetPath) response in
if response
// do stuff
我注意到的是,当我捕获 response 和 do stuff 时,调用此函数的类将永远不会 deinit。但是,如果我将功能更改为以下内容;
UploadHelper.shared.performUpload(url: fileAssetPath) response in
并且不对响应做任何事情,该类将取消初始化。
我的功能做错了什么?我想相应地捕获响应,但不以我的班级没有从内存中释放为代价。
【问题讨论】:
顺便说一句,虽然使用[weak self]
显然可以解决问题,但您完全有循环的事实很可能是由savePhotoRemote
将闭包保存在某些属性中引起的。本着防御性编程的精神,如果您曾经在属性中保存闭包,您可能还需要确保在调用闭包后nil
那个闭包属性(假设您不再需要它,就像这里的情况一样) .这并不能代替[weak self]
,而只是一个避免持续强引用循环的好习惯。
谢谢@Rob!这是非常有用的建议!
【参考方案1】:
你有一个保留周期。打破它。改变
UploadHelper.shared.performUpload(url: fileAssetPath) response in
if response
// do stuff
到
UploadHelper.shared.performUpload(url: fileAssetPath) [unowned self] response in
if response
// do stuff
【讨论】:
这是有道理的,并成功解决了我的问题。谢谢!以上是关于完成处理程序导致不调用 Deinit的主要内容,如果未能解决你的问题,请参考以下文章
AVAudioPlayerNode scheduleFile:atTime:completionHandler: 不调用完成处理程序