Swift 4:转义闭包只能通过值显式捕获 inout 参数
Posted
技术标签:
【中文标题】Swift 4:转义闭包只能通过值显式捕获 inout 参数【英文标题】:Swift 4: Escaping closures can only capture inout parameters explicitly by value 【发布时间】:2018-05-10 21:53:10 【问题描述】:我一直在将我的代码从 Swift 2 迁移到 Swift 4。我的以下代码在 Swift 2 中运行良好:
func fetchUserThumbnailAvatar(_ task : inout URLSessionTask?, completion : @escaping (_ image : UIImage?) -> ())
fetchUserAvatar(Session.currentUser?.avatar?.thumbnailURL as URL? ?? URL(string:"")!, externalUrl: URL(string: thumbnailAvatar) ?? URL(string:"")!, &task, completion: completion)
fileprivate func fetchUserAvatar(_ internalUrl : URL, externalUrl : URL,_ task : inout URLSessionTask?, completion : @escaping (_ image : UIImage?) -> ())
fetchImage(externalUrl, task: &task, completion: image in
if image == nil
self.fetchImage(internalUrl, task: &task, completion: completion)
else
self.cache.removeObject(forKey: (internalUrl.path as AnyObject?)! )
completion(image)
)
但是,转换后我收到以下错误:
转义闭包只能通过值显式捕获inout参数
在线:
if image == nil
self.fetchImage(internalUrl, task: &task, completion: completion)
如果有人可以帮助我,那就太好了。谢谢。
【问题讨论】:
请显示fetchImage
函数的代码
@George_E_2: fetchImage
不是问题。问题是task
作为fetchImage
的inout 参数给出,并且周围的闭包已经转义。看我的回答。
【参考方案1】:
错误详细描述in this answer。
你的代码的问题是第一个闭包
fileprivate func fetchUserAvatar(_ internalUrl : URL, externalUrl : URL,_ task : inout URLSessionTask?, completion : @escaping (_ image : UIImage?) -> ())
fetchImage(externalUrl, task: &task, completion: image in // <-- HERE --
if image == nil
是一个转义闭包。所以当代码
if image == nil
self.fetchImage(internalUrl, task: &task, completion: completion) // <-- HERE --
else
尝试写入task
变量,原来的fetchUserAvatar
调用已经完成。
注意:我已将类似 <-- HERE --
的 cmets 写入 sn-ps,以澄清我在说哪一行。另外,请务必查看我上面链接的答案,因为它会澄清一切..
坏消息是您将不得不稍微重构代码以修复错误。为此,您需要更改fetchUserThumbnailAvatar
和fetchUserAvatar
的签名,这会破坏调用者;所以调用者也必须改变。因此我无法为您修复它,因为修复取决于我没有的代码。
【讨论】:
以上是关于Swift 4:转义闭包只能通过值显式捕获 inout 参数的主要内容,如果未能解决你的问题,请参考以下文章
在 Swift 3.0 中的转义闭包中改变自我(结构/枚举)