2014-10-04 8 views
15

In Swift muss ich oft einen Noop-Abschluss zu einer Methode übergeben, nur um die erwarteten Parameter der Methode zu erfüllen (Arity). In den guten alten Tagen von Obj C konnte man nil für einen Noop-Rückruf passieren und damit fertig sein. Gibt es einen schnelleren, eleganteren Weg, dies in Swift zu tun, ohne einen leeren Block wie unten zu passieren?Elegante Methode, um leere Verschlüsse in Swift zu übergeben

UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: { (UIAlertAction) -> Void in }) // do nothing in callback

Komplettes Beispiel:

import UIKit 

class UIAlertControllerFactory { 
    class func ok(title: String, message: String) -> UIAlertController { 
     var alertController = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert) 
     var okAction = UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: { (UIAlertAction) -> Void in 
     }) 
     alertController.addAction(okAction) 
     return alertController 
    } 
} 

Antwort

26

Die allgemeine Art und Weise, wenn Sie nil nicht passieren:

var okAction = UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, 
    handler:{ _ in }) 

Sie auch nil in diesem Fall passieren kann, weil (wie von iOS 9.0) ist der Handler ein Optional:

var okAction = UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, 
    handler:nil) 
+0

Ich schwor nil nicht funktioniert in einem der Betas. Danke, ich mag auch den Ansatz. – dimroc

+2

'Handler' ist vom Typ' ((UIAlertAction!) -> Void)! ', Was bedeutet, dass es sich um eine implizit nicht abgewickelte Option handelt. Deshalb können Sie für diesen Parameter "Null" übergeben. Es ist dokumentiert (siehe meine Antwort für weitere Details). –

+0

Ein '!' - Suffix bedeutet ein 'ImplicitlyUnwrappedOptional', das Apple (in APIs) meistens verwendet, um anzuzeigen, dass sie nicht überprüft haben, ob 'nil' legal ist oder nicht. In iOS 9.0 haben sie den Typ in '((UIAlertAction) -> Void)?' Geändert, was bedeutet, dass sie verifiziert haben, dass "nil" erlaubt ist. –

3
extension UIAlertAction { 
    convenience init(title: String, style: UIAlertActionStyle) { 
     return self.init(title: title, style: style, handler: { (UIAlertAction) -> Void in }) 
    } 
} 

und lassen Sie das letzte Argument einfach weg. Sie können dies in Ihre "Fabrik" legen.

5

Nach Xcode-Dokumentation hat UIAlertAction eine convenience init Methode mit folgenden Erklärung:

convenience init(title: String, style: UIAlertActionStyle, handler: ((UIAlertAction!) -> Void)!) 

Wie Sie sehen können, die handler Parameter sind ein Implizit Unwrapped Optional vom Typ ((UIAlertAction!) -> Void)!. Sie können also nil dafür übergeben. Zum Beispiel können Sie eine UIAlertController Instanz erstellen, die eine UIAlertAction mit handler: nil enthält:

let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .ActionSheet) 
alertController.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)) 
presentViewController(alertController, animated: true, completion: nil) 

Daher Sie brauchen nicht einen leeren Block für handler zu erstellen.

5

Sie könnten einen noop definieren als Standardverschluss verwendet werden, die nichts tut: (Referenz: https://realm.io/news/closures-api-design)

func noop() {} 

func noop<T>(value: T) {} 

func noop<T>() -> T? { return nil } 

func noop<T, S>(value: T) -> S? { return nil } 

zu benutzen:

var okAction = UIAlertAction(title: "Ok", 
          style: UIAlertActionStyle.Default, 
          handler: noop) 
+0

Handlich für Fälle, in denen ein Parameter, der eine Schließung akzeptiert, nicht nullbar ist. (Der Fall 'UIAlertAction' in der Frage ist jedoch nullfähig.) Möglicherweise benötigen Sie auch einige andere Varianten für die APIs, die keine' @convention (block) '- Verschlüsse enthalten. – rickster

Verwandte Themen