2017-11-28 1 views
1

Ich habe eine Methode, die eingerichtet werden summiert kann wie folgt aussehen:Rückgabe nach dem Aufruf des Beendigungshandlers oder Rückgabe des Beendigungshandlerparameters?

func apply(username: String, email: String, password: String, 
      onDone: @escaping (_ error: Error?) ->()) 
{ 
    //Do async stuff 
    do 
    { 
     try asyncGood() 
     onDone(nil) 
     return 
    } 
    catch 
    { 
     onDone(error) 
     return 
    } 
} 

Was ist der Unterschied zwischen tun:

return onDone(error) 

gegen

onDone(error) 
return 

?
Speichert es nur eine zusätzliche Codezeile? Ich sehe keinen Unterschied zwischen den beiden. Fehle mir ein grundlegender Aspekt der asynchronen Swift-Programmierung?

Sollte ich Ihrer Meinung nach immer versuchen, alles so zusammenzufassen, dass onDone (...) am Ende nur einmal heißt?

+0

Viele Leute sagen, Return-Statements sind überhaupt nicht notwendig, und ich bekomme das. Aber wenn es mehrere Codepfade gibt, die 'onDone (...)' aufrufen, habe ich festgestellt, dass es mehrere Male aufgerufen wird, wodurch der nachfolgende Code mehrere Male aufgerufen wird. Deshalb beende ich meine 'onDone (...)' 's immer mit Return-Statements aus Gewohnheit. –

Antwort

1

Semantisch sind beide Fälle gleich. Sie sind im Grunde sagen:

return() 

Ihre Methode () zurückzukehren deklariert wird, und da die onDone Schließung auch eine () zurückgibt, können Sie return onDone(error) sagen. Die Rückgabetypen stimmen überein.

Allerdings finde ich schreibe sie in zwei separate Leitungen besser lesbar:

// This clearly shows that you are doing 2 separate things 
onDone(error) // call the completion handler 
return // return 

oder sogar die return weglassen!

1

Beide sind gleich. apply Funktion Rückgabetyp ist Void und onDone Schließung Rückgabetyp ist auch Void. Also sind beide gleich.

return onDone(error) 

oder

onDone(error) 
return 

oder Sie können einfach ignorieren, weil Rückkehr Rückgabetyp ist Void

onDone(error) 
1

gibt es keinen Unterschied. In der Tat gibt es keine Notwendigkeit für return Schlüsselwort überhaupt.

Für rasche alle folgende Erklärung entspricht:

func doNothing() { 
} 

func doNothing2() -> Void { 
} 

func doNothing3() ->() { 
} 

func doNothing4() { 
    return() 
} 

func doNothing5() -> Void { 
    return() 
} 

Wenn Sie zurückkommen() Sie nichts zurück. Keine Rückkehr ist genau das gleiche wie nichts zurückgeben.Funktionen Void Rückkehr kann in äquivalenter Weise, wie folgend

doNothing() 

var result = doNothing() 

Mehr, Void auch als Typ-Parameter verwendet werden können, verwendet werden, die ein sehr mächtiges Feature ist:

func genericCall<T>(_ f:() -> T) -> T { 
    return f() 
} 

var result1 = genericCall { print("test") } // result1 is Void 
var result2 = genericCall { return 5 } // result2 is Int 

Ihre erste Frage zu beantworten, würde ich vorschlagen,

func doStuffAsync(_ callback: @escaping (Error?) -> Void) { 
    // Just an example. Could be any other async call. 
    DispatchQueue.main.async { 
     do { 
      try doStuff() 
      callback(nil) 
     } 
     catch { 
      callback(error) 
     } 
    } 
} 
+0

Beachten Sie, dass asynchrone Methoden im Allgemeinen auch ein optionales Objekt zusammen mit dem optionalen Fehler zurückgeben. –

+0

Wenn es so schlecht ist, warum würde Apple es in URLSession-Methoden verwenden? –

+0

Ich stimme nicht zu "schlechtes Design" –

Verwandte Themen