Quick completion block

I find it difficult to understand the problem that I am experiencing. To simplify, I will use the UIView method. Basically, if I write a method

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

It works great. Now, if I make the same method, but by creating a line like this:

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

It stops working. Compiler Error: Missing argument for delay parameter when invoked

Now, here is the weird part. If I do the same code as the one that fails, but just add a print command like this:

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

it will start working again.

My problem is basically the same. My code is:

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

Does not work. But if I move on.

  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 great. I do not understand why this is happening. I almost agree that this is a compiler error.

+7
ios block swift xcode6
source share
1 answer

Closures in Swift have implicit returns when they consist of only one expression . This allows you to use compressed code, for example:

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

In your case, when you create your line here:

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

you end up returning this line and that makes the signature of your closure:

 (Bool) -> String 

This no longer matches what is required under the animateWithDuration signature (which leads to the Swift cryptic Missing argument for parameter 'delay' in call error, because it cannot find the appropriate signature to match).

An easy fix is ​​to add an empty return statement at the end of your closure:

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

What 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, not one; Implicit returns occur only when the closure contains one expression. So, this closure does not return anything and matches its signature.

+10
source share

All Articles