automatische Vervollständigung wird Ihnen helfen, aber im Grunde, wenn Foo
eine Klasse ist, müssen Sie nur eine Methode, die die genaue Signatur der Methode in Ihrem Protokoll übereinstimmt:
class Foo {}
protocol JSONInitializable {
static func initialize(fromJSON: [String : AnyObject]) throws -> Self?
}
extension Foo: JSONInitializable {
static func initialize(fromJSON: [String : AnyObject]) throws -> Self? {
return nil
}
}
als Notiz hier, müssen Sie innerhalb dieser Methode ersetzen alle Instanzen Foo
mit Self
. Wenn Sie einen Konstruktor verwenden möchten, muss dieser entsprechend markiert sein.
Vor diesem Hintergrund ist es wahrscheinlich sinnvoller, das Protokoll so zu ändern, dass statt einer statischen Methode initialize
ein Initialisierer erforderlich ist. In diesem Fall sollten Sie sich Blake Lockley's answer ansehen. Diese Antwort beantwortet jedoch die Frage, wie mit Self
in Protokollen umzugehen ist, da es sicherlich Fälle gibt, in denen wir eine Methode wünschen, die Self
zurückgibt, die kein Initialisierer ist.
Wenn Foo
keine Klasse ist, ist es ein Werttyp, der nicht Subklassen sein kann, und als solche, kehren wir den Namen des Typs:
struct Foo: JSONInitializable {
static func initialize(fromJSON: [String : AnyObject]) throws -> Foo? {
return nil
}
}
enum Foo: JSONInitializable {
case One, Two, Three
static func initialize(fromJSON: [String : AnyObject]) throws -> Foo? {
return nil
}
}
Der Grund, warum Sie im Fall einer Klasse Self?
von der Methode zurückgeben müssen, ist die Vererbung. Das Protokoll erklärt, dass Sie eine Methode namens initialize
haben, deren Rückgabetyp eine optionale Version dessen ist, was auch immer Sie sind.
Wenn wir Foo
‚s initialize
Methode schreiben, wie Sie es geschrieben hat, dann, wenn wir Foo
mit Bar
Unterklasse, dann jetzt haben wir unsere Übereinstimmung mit dem Protokoll gebrochen. Bar
hat die Konformität mit dem Protokoll von Foo
geerbt, aber es hat keine Methode, die initialize
heißt und Bar?
zurückgibt. Es hat einen, der Foo
zurückgibt.
Mit Self
bedeutet hier, dass, wenn unsere Unterklassen diese Methode erben, es zurückgibt, welcher Typ auch immer sie sind. Self
ist Swifts Äquivalent Objective-C's instancetype
.
So würde das ich Objekt vom Typ 'foo' aus dem Verfahren zurückkehren lassen? – smac89
Es gibt 'Foo' zurück, wenn Sie es auf einer Instanz von' Foo' aufrufen. Wenn Sie 'Foo' von der Klasse' Bar: Foo' ableiten, wird 'Bar' zurückgegeben. – nhgrif
Ich habe es gerade versucht und es gibt mir einen Fehler, wenn ich versuche, ein Objekt vom Typ 'Foo' von der Methode zurückzugeben. Es heißt 'Kann den Ausdruck des Typs 'Foo' nicht konvertieren, um den Typ 'Self' zurückzugeben. 'Ich benutze xcode 7.3, wenn das irgendwas hilft. – smac89