简体   繁体   English

Swift完成块

[英]Swift completion block

I'm having a hard time understanding a problem I'm having. 我很难理解我遇到的问题。 To simplify, I'll use UIView method. 为简化起见,我将使用UIView方法。 Basically, if I write the method 基本上,如果我写的方法

UIView.animateWithDuration(1, animations:  {() in
        }, completion:{(Bool)  in
            println("test")
    })

it works fine. 它工作正常。 Now, if I do the same method, but creating a string like so: 现在,如果我使用相同的方法,但创建一个这样的字符串:

    UIView.animateWithDuration(1, animations:  {() in
        }, completion:{(Bool)  in
            String(23)
    })

It stops working. 它停止工作。 Compiler error: Missing argument for parameter 'delay' in call 编译器错误: 在调用中缺少参数'delay'的参数

Now, here's the strange part. 现在,这是奇怪的部分。 If I do the exact same code as the one that fails, but just add a print command like so: 如果我执行与失败的代码完全相同的代码,但只需添加如下的打印命令:

   UIView.animateWithDuration(1, animations:  {() in
        }, completion:{(Bool)  in
            String(23)
            println("test")
    })

it starts to work again. 它又开始起作用了。

My problem is basically the same thing. 我的问题基本上是一回事。 My code: 我的代码:

   downloadImage(filePath, url: url) { () -> Void in
         self.delegate?.imageDownloader(self, posterPath: posterPath)
        }

Doesn't work. 不行。 But if I change to. 但如果我换到。

 downloadImage(filePath, url: url) { () -> Void in
             self.delegate?.imageDownloader(self, posterPath: posterPath)
                println("test")
            }

or even: 甚至:

downloadImage(filePath, url: url) { () -> Void in
             self.delegate?.imageDownloader(self, posterPath: posterPath)
             self.delegate?.imageDownloader(self, posterPath: posterPath)
            }

It works fine. 它工作正常。 I can't understand why this is happening. 我不明白为什么会这样。 I'm close to accept that it's a compiler bug. 我接近它接受它是一个编译器错误。

Closures in Swift have implicit returns when they are only made up of a single expression . 当Swift仅由单个表达式组成时,它们具有隐式返回 This allow for succinct code such as this: 这允许简洁的代码,例如:

reversed = sorted(names, { s1, s2 in s1 > s2 } )

In your case, when you create your string here: 在您的情况下,当您在此处创建字符串时:

UIView.animateWithDuration(1, animations:  {() in }, completion:{(Bool) in
    String(23)
})

you end up returning that string and that makes the signature of your closure: 你最终返回该字符串,这使得你的闭包签名:

(Bool) -> String

That no longer matches what's required by animateWithDuration 's signature (which translates to Swift's cryptic Missing argument for parameter 'delay' in call error because it can't find an appropriate signature to match). 这不再匹配animateWithDuration的签名所需的animateWithDuration (这Missing argument for parameter 'delay' in call错误中转换为Swift Missing argument for parameter 'delay' in call的神秘Missing argument for parameter 'delay' in call因为它无法找到匹配的适当签名)。

An easy fix is to add an empty return statement at the end of your closure: 一个简单的解决方法是在闭包结束时添加一个空的return语句:

UIView.animateWithDuration(1, animations:  {() in}, completion:{(Bool) in
    String(23)
    return
})

Which makes your signature what it should be: 这使你的签名应该是什么:

(Bool) -> ()

Your last example: 你最后一个例子:

downloadImage(filePath, url: url) { () -> Void in
    self.delegate?.imageDownloader(self, posterPath: posterPath)
    self.delegate?.imageDownloader(self, posterPath: posterPath)
}

works because there are two expressions there, not just one; 因为那里有两个表达式,而不仅仅是一个表达式; implicit returns only happen when the closure contains a single expression. 隐式返回仅在闭包包含单个表达式时发生。 So, that closure isn't returning anything and that matches its signature. 因此,该闭包不返回任何东西,并且与其签名相匹配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM