Swift完成块

时间:2014-09-21 02:37:42

标签: ios swift block xcode6

我很难理解我遇到的问题。 为简化起见,我将使用UIView方法。 基本上,如果我写方法

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

它工作正常。 现在,如果我使用相同的方法,但创建一个类似的字符串:

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

它停止工作。编译错误:缺少参数'延迟'在电话中

现在,这是一个奇怪的部分。如果我执行与失败的代码完全相同的代码,但只需添加如下的打印命令:

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

它再次开始工作。

我的问题基本上是一回事。我的代码:

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

不起作用。但如果我换到。

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

甚至:

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

工作正常。 我无法理解为什么会这样。我接近它接受它是一个编译器错误。

1 个答案:

答案 0 :(得分:10)

Swift中的闭包只有 implicit returns ,只有单个表达式。这允许简洁的代码,例如:

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

在您的情况下,当您在此处创建字符串时:

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

你最终会返回该字符串,这会使你的闭包签名:

(Bool) -> String

它不再符合animateWithDuration签名所要求的内容(这会转换为Swift的神秘Missing argument for parameter 'delay' in call错误,因为它无法找到匹配的相应签名。)

一个简单的解决方法是在闭包结束时添加一个空的return语句:

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

这使你的签名应该是什么:

(Bool) -> ()

你的最后一个例子:

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

有效,因为那里有两个表达式,而不仅仅是一个;隐式返回仅在闭包包含单个表达式时发生。因此,该闭包不会返回任何内容并且与其签名相匹配。