2015-09-23 7 views
5

Ich habe eine Situation, in der ich versuche, NSError zu überschreiben, um mir eine Instanz eines Fehlers zu liefern. Ich werde viel wiederverwenden ."Kann 'init', das als nicht verfügbar markiert wurde, nicht überschreiben" verhindert das Überschreiben leerer Init

Mein Code arbeitete, bis ich Xcode aktualisiert und konvertiert Swift 2.

public class NAUnexpectedResponseTypeError: NSError { 
    public convenience init() { 
     let messasge = "The object fetched by AFNetworking was not of an expected type." 
     self.init(
      domain: "MyDomain", 
      code: 6782, 
      userInfo: [NSLocalizedDescriptionKey: messasge] 
     ) 
    } 
} 

Der Compiler sagt Cannot override 'init' which has been marked unavailable. Ich war in der Lage, um es zu hacken um dies zu tun:

public class NAUnexpectedResponseTypeError: NSError { 
    public class func error() -> NSError { 
     let message = "The object fetched by AFNetworking was not of an expected type." 
     return NAUnexpectedResponseTypeError(
      domain: "MyDomain", 
      code: 6782, 
      userInfo: [NSLocalizedDescriptionKey: message] 
     ) 
    } 
} 

Also, meine Frage ist:

  1. Gibt es eine Möglichkeit eine leere init Methode in einer Situation wie diese hinzufügen?
  2. Wenn ja zu 1, ist das aus irgendeinem Grund eine schlechte Idee?
  3. Ist meine Problemumgehung mit der Klassenmethode ein geeigneter Weg, um dieses Problem zu lindern?

EDIT:

Ich kam mit einem anderen Problem zu umgehen bis die Ich mag besser als die Abhilfe mit der Klassenmethode. Ich bin immer noch nicht glücklich, dass ich die leere init Methode nicht überschreiben kann.

public class NAUnexpectedResponseTypeError: NSError { 
    public convenience init(message: String?) { 
     var errorMessage: String 
     if let message = message { 
      errorMessage = message 
     } else { 
      errorMessage = "The object fetched by AFNetworking was not of an expected type." 
     } 
     self.init(
      domain: "MyDomain", 
      code: 6782, 
      userInfo: [NSLocalizedDescriptionKey: errorMessage] 
     ) 
    } 
} 
+1

Fügen Sie Ihrer Klasse mehr Code hinzu als hier gezeigt? Weil ich mich frage, warum eine Unterklasse überhaupt notwendig ist. –

+0

@TomHarrington Würdest du etwas wie eine Erweiterung für NSError vorschlagen? – Jonathan

Antwort

3

Da NSError unveränderlich ist, gibt es keinen Grund, mehrere Instanzen der gleichen Daten zu erstellen. Erstellen Sie einfach eine einzige Konstante, Beispiel:

let NAUnexpectedResponseTypeError = NSError(domain: "MyDomain", 
    code: 6782, 
    userInfo: [NSLocalizedDescriptionKey: "The object fetched by AFNetworking was not of an expected type."] 
) 

Wenn Sie eine Situation haben, die nicht konstant ist, dann ist es fast immer besser ist, statt NSError Unterklasse zu erweitern. Zum Beispiel:

extension NSError { 
    class func MyError(code code:code, message: String) -> NSError { 
     return NSError(domain: "MyDomain", 
         code: code, 
         userInfo: [NSLocalizedDescriptionKey: message]) 
    } 
} 

Diese Art der Erweiterung (als Kategorie) hat eine lange Geschichte in ObjC, und ist ein gutes Muster zu Swift bringen (wenn Sie enum ErrorTypes nicht leicht verwenden können, die noch besser sind Schnell).

In vielen Fällen finde ich es noch einfacher, nur eine Top-Level-Funktion dafür zu haben, anstatt NSError zu erweitern. Zum Beispiel:

private func makeError(code code:code, message: String) -> NSError { 
    return NSError(domain: "MyDomain", 
        code: code, 
        userInfo: [NSLocalizedDescriptionKey: message]) 
} 

(Ich persönlich verwende diese Art von Funktionen die ganze Zeit in Swift, wenn ich NSError verwenden In ObjC, I Kategorien der Regel auf NSError verwenden nicht sicher, warum ich mich verändert, aber es fühlt sich mehr.. natürlich.)

+0

Sehr hilfreich und gründlich. Danke vielmals! – Jonathan

3

Sie können die leere Init nicht überschreiben, sie ist als nicht verfügbar gekennzeichnet, damit Sie nichts damit anfangen können.

Sie tun eine andere Abhilfe haben, obwohl

public class NAUnexpectedResponseTypeError: NSError { 

    public convenience init(message: String = "The object fetched by AFNetworking was not of an expected type.") { 
      self.init(
       domain: "MyDomain", 
       code: 6782, 
       userInfo: [NSLocalizedDescriptionKey: message] 
     ) 
    } 
} 

ich es nicht testen, aber es sollte funktionieren.

Da Sie mit swift 2.0 arbeiten, sollten Sie Ihre Instanz nicht dem Fehlertyp anpassen, statt NSError abzuleiten. Es wäre sauberer und idiomatischer.

Verwandte Themen