2014-09-21 6 views
7

Ich habe eine schwere Zeit zu verstehen, ein Problem, das ich habe. Um zu vereinfachen, verwende ich die UIView-Methode. Grundsätzlich, wenn ich die MethodeSwift Completion Block

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

schreiben funktioniert es gut. Nun, wenn ich die gleiche Methode, aber eine Zeichenfolge wie so erstellen:

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

es nicht mehr funktioniert. Compiler-Fehler: Fehlendes Argument für Parameter 'Verzögerung' im Aufruf

Nun, hier ist der seltsame Teil. Wenn ich den exakt gleichen Code wie das zu tun, die fehlschlägt, aber nur einen Druckbefehl hinzufügen, etwa so:

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

es beginnt wieder zu arbeiten.

Mein Problem ist im Grunde das Gleiche. Mein Code:

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

Funktioniert nicht. Aber wenn ich mich ändere.

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

oder sogar:

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

Es funktioniert gut. Ich kann nicht verstehen, warum das passiert. Ich bin nah dran zu akzeptieren, dass es ein Compiler Bug ist.

Antwort

10

Closures in Swift hat implicit returns, wenn sie nur aus einem einzigen Ausdruck gemacht werden. Diese ermöglichen eine prägnante Code wie folgt aus:

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

In Ihrem Fall, wenn Sie Ihre Zeichenfolge erstellen hier:

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

Sie diese Zeichenfolge Rückkehr am Ende, und das macht die Unterschrift Ihrer Schließung:

(Bool) -> String 

Dass nicht mehr übereinstimmt, was durch animateWithDuration ‚Unterschrift erforderlich ist (die Swift kryptische Missing argument for parameter 'delay' in call Fehler übersetzt, weil es nicht fi nden kann eine entsprechende Signatur finden).

Eine einfache Lösung ist eine leere return-Anweisung am Ende des Verschlusses hinzuzufügen:

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

Welche Ihre Unterschrift macht, was es sein sollte:

(Bool) ->() 

Ihr letztes Beispiel:

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

funktioniert, weil es zwei Ausdrücke gibt, nicht nur einen; implizite Rückgaben werden nur ausgeführt, wenn der Abschluss einen einzelnen Ausdruck enthält. Also, diese Schließung gibt nichts zurück und das entspricht ihrer Signatur.

+0

Danke. Aber warum scheitert es nicht, wenn ich String (23) hinzufüge und die gleiche Zeile wieder kopiere wie: String (23); Schnur (23); ? – Wak

+0

Ich war gerade dabei, das in der Antwort zu klären. Siehe Bearbeiten. –

+0

Danke für diese Antwort; half mir herauszufinden, warum ich eine seltsame "kann nicht animateWithDuration 'mit einem Argument Liste der Art ..." Fehler aufrufen. Es stellte sich heraus, dass der Fix genau gleich war. – SonarJetLens