2015-02-06 13 views
12

Ich verstehe nicht, warum Programmierer das Schlüsselwort extension in ihrer Klassenimplementierung verwenden. Sie können in anderen Themen lesen, dass Code dann semantisch getrennt ist usw. Aber wenn ich mit meinem eigenen Code arbeite, fühlt es sich für mich klarer an, // MARK - Something zu verwenden. Wenn Sie dann die Methodenliste (Strg + 6) in Xcode verwenden, wird alles auf den ersten Blick gesehen.Swift und Verwendung der Klassenerweiterung

In Apple-Dokumentation können Sie lesen:

„Erweiterungen neue Funktionalität zu einem vorhandenen Klasse, Struktur oder Aufzählungstyp hinzufügen“

Warum also nicht meinen eigenen Code direkt schreiben in meinem eigene Klasse? Anders als wenn ich die Funktionalität einiger ausländischer Klassen erweitern möchte, wie NSURLSession oder Dictionary, wo Sie verwenden, um Erweiterungen zu verwenden.

Mattt Thompson verwenden Erweiterung in seiner Alamofire-Bibliothek, vielleicht kann er mir wenig Erklärung geben, warum er diesen Ansatz wählte.

+0

Verwenden Sie, was Sie bevorzugen, aber die Erweiterung macht es expliziter als nur 'MARK:', deutlich, wo es beginnt und wo es endet. Ehrlich gesagt, es ist kein Entweder-oder-Problem, da ich sowohl "MARK:" als auch eine "Erweiterung" verwenden werde. Ein weiterer Vorteil von 'extension' ist, dass Sie diesen Code einfach falten können (z. B." Editor "-" Code Folding ... "-" Falten "oder klicken Sie auf den schattierten linken Rand). – Rob

Antwort

14

Für mich scheint es völlig in Ordnung, da Sie Erweiterungen verwenden können, um verschiedene Teile der Logik für verschiedene Erweiterungen verfügbar zu machen. Dies kann auch

auf Protokolle besser lesbar, zum Beispiel zu machen Klasse Konformität verwendet werden
class ViewController: UIViewController { 
... 
} 

extension ViewController: UITableViewDelegate { 
... 
} 

extension ViewController: UITableViewDataSource { 
... 
} 

extension ViewController: UITextFieldDelegate { 
... 
} 

Protokoll Methoden getrennt werden in verschiedenen Erweiterungen für Klarheit scheint dies viel besser zu lesen als sagen wir mal:

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {} 

Also, ich würde sagen, dass es keinen Schaden in der Verwendung von Erweiterungen, um Ihren eigenen Code lesbarer zu machen, nicht nur um bereits vorhandene Klassen von SDK zu erweitern. Durch die Verwendung von Erweiterungen können Sie vermeiden, dass große Teile des Codes in Ihren Controllern enthalten sind und die Funktionalität in leicht lesbare Teile aufgeteilt wird, so dass es keinen Nachteil hat, diese zu verwenden.

+0

Und was für NSCoding Protokoll? Sie können die Erweiterung für dieses Protokoll nicht verwenden. – Deny

+0

Hier wird es knifflig, Erweiterungen können keine bestimmten Initialisierer hinzufügen, daher sollte NSCodings 'init (coder:)' nicht über Erweiterungen implementiert werden, bin mir nicht so sicher. – libec

+0

Funktioniert nicht, wenn Sie auf etwas Privates aus der Klasse zugreifen müssen, die Sie erweitern, oder? Oder fehlt mir etwas? –

6

Mithilfe von Erweiterungen können Sie Ihre Protokollkonformitätserklärung neben den Methoden, die dieses Protokoll implementieren, beibehalten.

Wenn es keine Erweiterungen waren, stellen Sie sich Ihre Art, wie erklärt:

struct Queue<T>: SequenceType, ArrayLiteralConvertible, Equatable, Printable, Deflectable, VariousOtherables { 

// lotsa code... 

// and here we find the implementation of ArrayLiteralConvertible 
    /// Create an instance containing `elements`. 
    init(arrayLiteral elements: T…) { 
     etc 
    } 

} 

Kontrast dies bei der Verwendung von Erweiterungen, in dem Sie die Umsetzung der Protokolle mit den spezifischen Methoden bündeln, die sie implementieren:

struct Queue<T> { 
    // here go the basics of queue - the essential member variables, 
    // maybe the enqueue and dequeue methods 
} 

extension SequenceType { 
    // here go just the specifics of what you need for a sequence type 
    typealias Generator = GeneratorOf<T> 
    func generate() -> Generator { 
     return GeneratorOf { 
      // etc. 
     } 
    } 
} 

extension Queue: ArrayLiteralConvertible { 
    init(arrayLiteral elements: T...) { 
     // etc. 
    } 
} 

Ja, Sie können Ihre Protokollimplementierungen mit // MARK markieren (und beachten Sie, Sie können beide Techniken kombinieren), aber Sie würden immer noch über den Anfang der Datei aufgeteilt werden, wo die Erklärung der Protokollunterstützung würde b e und der Hauptteil der Datei, in der sich Ihre Implementierung befindet.

Denken Sie auch daran, wenn Sie ein Protokoll implementieren, erhalten Sie hilfreiche (wenn auch etwas wortreiche) Rückmeldungen von der IDE, während Sie fortfahren und Ihnen sagen, was Sie noch implementieren müssen. Das Verwenden von Erweiterungen, um jedes Protokoll einzeln zu machen, macht es für mich viel einfacher, als alles auf einmal zu tun (oder von oben nach unten zu springen, wenn du sie hinzufügst).

Vor diesem Hintergrund ist es natürlich, andere, nicht-Protokoll, sondern verwandte Methoden auch in Erweiterungen zu gruppieren.

Ich finde es tatsächlich manchmal frustrierend, wenn Sie nicht können dies tun. Zum Beispiel

extension Queue: CollectionType { 
    // amongst other things, subscript get: 
    subscript(idx: Index) -> T { 
     // etc 
    } 
} 

// all MutableCollectionType adds is a subscript setter 
extension Queue: MutableCollectionType { 
    // this is not valid - you’re redeclaring subscript(Index) 
    subscript(idx: Int) -> T { 
     // and this is not valid - you must declare 
     // a get when you declare a set 
     set(val) { 
      // etc 
     } 
    } 
} 

Also müssen Sie beide innerhalb der gleichen Erweiterung implementieren.

+1

Ok, wenn Sie also Ihren Klassenquellcode einige Seiten lang haben, sehen Sie nicht, welche Protokolle diese Klasse implementiert. Sie müssen diese Informationen durch den Code suchen. Für mich ist das nicht klarer als mit // MARK im Code. – Deny

+0

Pferde für Kurse, aber ich würde sagen, dass die Verwendung der Sprache statt der Kommentare, um die Absicht anzuzeigen, klarer ist. Sehen Sie auch meine Bearbeitung, es macht die Implementierung der Protokolle, wie Sie in meiner Erfahrung einfacher gehen. –

+0

Vielen Dank für Ihre Meinung. Ich werde versuchen, beide Ansätze zu kombinieren - Erweiterungen zu verwenden und sie mit // MARK zu markieren. – Deny

Verwandte Themen