2015-08-06 8 views
6

Ich möchte eine Helper.swift Datei erstellen, um einige Funktionen/Methoden hinzuzufügen, die in verschiedenen Teilen meiner App nützlich sind.Verwenden einer Funktion oder einer Typmethode?

Ich frage mich, was ist die beste Praxis (wenn es eine gibt): eine Klasse erstellen und nur Typ Methoden erstellen oder nur Funktionen erstellen?

+0

Ich denke, Sie sollten als Klassenfunktion verwenden. –

Antwort

4

Ich würde in der Regel neigen, mit einem Typ Methoden auf einem entsprechend benannten Typ, um Ihre Hilfsmethoden Kontext geben und die Verschmutzung des globalen Namespace zu vermeiden.

In Swift, structs sind ein idealer Kandidat für diese Art von Konstrukt:

struct Helper { 
    static func helpfulMethod() { ... } 
} 

Ich benutze auch eingebettete structs mit statischen Konstanten recht großzügig in meinen Top-Level-Typen, um in meinem Code, um verwandten Konstanten.

In benutzerdefinierten Swift-Typen schreiben, sollten Sie in der Regel betrachten structs zuerst, und nur auf Klassen zurückgreifen, wenn Vererbung Referenzsemantik (im Gegensatz zu dem impliziten Kopieren mit Wertesemantik) oder Eigentum Semantik (unowned/weak) erforderlich verwenden. In diesem Fall sind Ihre Dienstprogrammfunktionen zustandslos und es gibt keine Vererbung, von der gesprochen werden sollte. Daher sollte eine Struktur einer Klasse vorgezogen werden.

Ich würde argumentieren, dass die Swift-Sprache im Allgemeinen von globalen Funktionen zugunsten des impliziten Namespacings von Typen (und Protokollen/Generika) wegbewegt. Aber es ist immer noch weitgehend eine Frage des Stils/der persönlichen Vorliebe, und für etwas so einfaches wie eine Dienstprogrammfunktion ist es von geringer Konsequenz.

0

Lösung # 1:

class Helper { 
    class func classMethod() { 
     // TODO: play something 
    } 
} 

Und es nennen:

Helper.classMethod() 

in Apple doc:

Strukturen werden immer kopiert, wenn sie um in Ihrem Code übergeben werden und verwenden Sie keine Referenzzählung.

Lösung # 2:

struct Helper { 
    static func classMethod() { 
     // TODO: do something 
    } 
} 

und es verwenden:

Helper.classMethod() 

Ich denke Lösung # 2 besser als Lösung # 1, weil es einen Referenzzähler nicht erhöht ist .

AKTUALISIERT: Ich habe mit playground getestet. Siehe das Ergebnis unten:

enter image description here Hoffe, das hilft!

+0

ok, aber was ist es besser als nur 'func classMethod() { // TODO: play something }'? – Nico

+0

Mit helper-Methode erstellen Sie eine 'Instanz-Methode' ist wirklich nicht notwendig. –

0

Ich weiß nicht, ob es die beste Praxis ist, aber hier ist, wie ich es mache.

Zuerst erkläre ich ein Protokoll:

protocol UtilityType { } 

Dann habe ich es erweitern (zB eine Nutzenfunktion für UIViewController)

extension UtilityType where Self: UIViewController { 
    func setDefaultTitleAttributes() { 
     navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.whiteColor()] 
    } 
} 

Und ich benutze es wie dieses

class MyViewController: UIViewController { 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     setDefaultTitleAttributes() 
    } 
} 

extension MyViewController: UtilityType {} 
+0

Erweiterungen von Protokollen funktionieren nur auf Swift 2, wenn ich nicht falsch liege. – Nico

1

Es ist nicht notwendig, eine Klasse oder eine Struktur zu erstellen. Sie können die Funktionen einfach direkt in die Datei Helper.swift stellen. Und Sie müssen nicht einmal diese Datei importieren, indem Sie import-Anweisungen schreiben.

Um es auszuprobieren, erstellen Sie eine Datei namens helper.swift und fügen Sie einfach die folgenden Codezeilen zur Datei hinzu. Keine Klasse oder Struktur ist erforderlich.

import Foundation 

func addTwo(x: Int) { 
    return x+2 
} 

Um diese Funktion in jeder anderen Datei verwenden nur die Funktion mit den erforderlichen Argumenten aufrufen.

Ich bevorzuge diese Methode, denn wenn Sie die Funktion aufrufen, müssen Sie sie nicht auf einer Instanz einer Klasse/Struktur aufrufen. Zweitens führt es zu einem saubereren Code, da Sie nicht jede Funktion zu einer Klassenfunktion oder statischen Funktion machen müssen.

+1

Ich denke @Nico erkannte, dass dies eine Option war, aber suchte nach einer Diskussion der Vorzüge jedes Ansatzes (globale Funktion vs. Typ-Methode). Das ist jedoch nicht weg von Ihrem letzten Absatz, wo Sie die Vorteile dieses Ansatzes diskutieren :). – Stuart

+0

@Stuart Ich habe diese Antwort nur hinzugefügt, um darauf hinzuweisen, dass dies auch eine Möglichkeit ist. Und der Vorteil dieses Ansatzes ist weniger Code. –

+0

Ja, genau das habe ich mit einer Konstante gemacht. Es ist in der Tat schneller zu schreiben und vielleicht klarer in der Datei, in der Sie sie erstellen, aber ich stimme der Antwort von @Stuart in der Art zu, dass es einen Kontext gibt. Und mir ist klar, dass es mir helfen kann, wenn ich mich nicht an den Namen der Methode/Konstante erinnere, aber ich habe nicht den Kontext (oder die Klasse in diesem Fall) – Nico

1

Ich bevorzuge Typ-Methode, weil auf diese Weise können Sie Ihre Methoden leicht unterscheiden.

Angenommen, Sie haben 50 bis 60 Methoden, in denen einige Methoden zum Entwerfen Zweck, einige Methoden sind für Berechnungszwecke und einige Methoden sind zum Abrufen und Veröffentlichen von Daten auf dem Server.

Wenn Sie nun alle diese Methoden global erstellen, wird es in diesem Szenario schwierig, sie zu erkennen und sich daran zu erinnern.

Nun, wenn Sie wie unter dieser Methoden in irgendeiner Klasse/Struktur unterscheiden:

  • Methoden, die Nutzung sind für die Gestaltung Zweck eine DesignHelper Klasse/Struktur machen und all diese Methoden setzen in sie als class/static method
  • Methods welche Verwendung für die Berechnung Zweck eine MathHelper Klasse machen/Struktur und setzen alle diese Verfahren in sie als class/static method
  • Methoden, die Verwendung für Prozessdaten mit Server sind machen eine ConnectionHelper Klasse/Struktur und setzen alle th ese Methode in sie als class/static method

auf diese Weise Durch die Verwendung Sie einfach eine der Methode herausfinden können, und es wird auch in auto completion helfen.

Vielen Dank.

1

Klassenfunktionen funktionieren nur in einer Klasse, aber im Allgemeinen werden die Funktionen, die in Ihrer App verwendet werden, auf denselben Objekten ausgeführt. Ein saubererer Weg besteht darin, Ihre Funktionen in Erweiterungen des Objekts zu definieren, das die Funktion verwendet. Sie können alle Ihre Erweiterungen in Helper.swift

z.

extension UIColor 
{ 
    class func randomColor() -> UIColor 
    { 
     var randomRed:CGFloat = CGFloat(drand48()) 
     var randomGreen:CGFloat = CGFloat(drand48()) 
     var randomBlue:CGFloat = CGFloat(drand48()) 

     return UIColor(red: randomRed, green: randomGreen, blue: randomBlue, alpha: 1.0) 
    } 
} 

mit Nutzung wie diese page.backgroundColor = UIColor.randomColor()

So können Sie Ihre Funktionen als Klassenfunktionen oder Objektfunktionen abhängig von der Verwendung, aber innerhalb der Erweiterung des Objekts definieren.

Dies hält Ihren Code frei, so dass Sie Ihre Anrufe nicht durch den Helfer in Ihrer Codebasis weiterleiten. Es ist klar definiert für das Objekt, das die Funktion benötigt. Wenn Sie Code finden, der in einer erweiterten Funktion keinen Sinn ergibt, muss die Funktion wahrscheinlich in eine stärker fokussierte Funktion umgestaltet werden.

Verwandte Themen