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调用已经完成。

注意:我已将类似 &lt;-- HERE -- 的 cmets 写入 sn-ps,以澄清我在说哪一行。另外,请务必查看我上面链接的答案,因为它会澄清一切..

坏消息是您将不得不稍微重构代码以修复错误。为此,您需要更改fetchUserThumbnailAvatarfetchUserAvatar 的签名,这会破坏调用者;所以调用者也必须改变。因此我无法为您修复它,因为修复取决于我没有的代码。

【讨论】:

以上是关于Swift 4:转义闭包只能通过值显式捕获 inout 参数的主要内容,如果未能解决你的问题,请参考以下文章

Swift 5:转义闭包捕获'inout'参数

转义闭包捕获 Swift 中的变异“self”参数错误

如何解决转义闭包捕获 Swift 中的“inout”参数?

在 Swift 3.0 中的转义闭包中改变自我(结构/枚举)

Alamofire 4、Swift 3:无法返回 StatusCode

有没有办法在函数调用中通过引用传递和通过值显式传递?