2015-11-13 1 views
11

Ich versuche, einen fehlgeleiteten Initialisierer für eine Klasse zu erstellen. Meine Klasse wird mit der Eingabe einer Netzwerkanforderung initialisiert. Netzwerke sind unzuverlässig, ich möchte einen Initialisierer erstellen, der das Vorhandensein auf allen Eigenschaften überprüft und andernfalls fehlschlägt.Ambiguous Verweis auf Mitglied 'tiefgestellt' auf Dictionary

Ich versuche, hier Verwendung von Schutz zu machen, also bitte keine offensichtlichen Fehler bei der Annäherung an Punkt frei fühlen:

public class JobModel { 
    let jobId: String 
    let status: String 
    let toName: String 
    let toAddress: String 
    let description: String 
    let fee: Int 
    let jobDate: NSDate 
    let fromName: String 
    let fromAddress: String 

    init?(job: [String:AnyObject]) throws { 
     guard self.jobId = job["jobid"] as! String else { 
      throw InitializationError.MissingJobId 
     } 

    } 
} 

Die guard self.jobId Linie versagt zu kompilieren, mit Fehlern: Ambiguous reference to member 'subscript'

Haben Sie Ideen, wie Sie diesen Fehler beheben können?

+0

Wollen Sie * * fail (dh Rückkehr 'nil') oder * throw * ein Fehler, wenn die Eigenschaft nicht vorhanden ist? Das sind zwei verschiedene Dinge. –

+1

Die Fehlermeldung scheint irreführend zu sein: Der Ausdruck nach der 'guard'-Anweisung muss ein boolesches Ergebnis oder das Bewertungsergebnis einer optionalen Bindung haben (' let'-Syntax). Erwägen Sie, das Eingabewörterbuch * vor dem Aufruf des Initialisierers zu validieren. – vadian

+0

@MartinR, Ich würde es vorziehen, einen Fehler zu werfen, da der Anrufer des Initialisierers wissen wird, warum die Initialisierung fehlgeschlagen ist, Kontext, den der Anrufer nicht erhalten wird, indem er Null zurückgibt. –

Antwort

8

Guard erfordert eine Bedingung, die BooleanType entspricht. Einfache Zuordnung nicht. Du brauchst so etwas.

guard let j = job["jobid"] as? String else { 
    throw InitializationError.MissingJobId 
} 
self.jobId = j 

aber dann werden Sie den Fehler erhalten „alle gespeicherten Eigenschaften einer Klasse-Instanz muss, bevor von einem initializer werfen initialisiert werden.“ Es wird erwartet, und dokumentiert in der The Swift Programming Language:

For classes, however, a failable initializer can trigger an initialization failure only after all stored properties introduced by that class have been set to an initial value and any initializer delegation has taken place.

Chris Lattner erwähnt das aktuelle Verhalten ist hier unerwünscht: http://swift-language.2336117.n4.nabble.com/Swift-2-throwing-in-initializers-td439.html