2015-09-23 1 views
5

Ho una situazione in cui sto cercando di ignorare NSError per fornirmi un'istanza di un errore che sto per riutilizzare molto ."Impossibile sovrascrivere 'init' che è stato contrassegnato come non disponibile" previene l'override vuoto init

Il mio codice stava lavorando fino a quando ho aggiornato Xcode e convertito in 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] 
     ) 
    } 
} 

Il compilatore dice Cannot override 'init' which has been marked unavailable. Sono stato in grado di incidere intorno ad esso in questo modo:

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] 
     ) 
    } 
} 

Quindi, la mia domanda è:

  1. Esiste un modo per aggiungere un metodo vuoto init in una situazione come questa?
  2. Se si a 1, è una cattiva idea per qualche motivo?
  3. La mia soluzione alternativa al metodo di classe è un modo appropriato per mitigare questo problema?

EDIT:

mi si avvicinò con un'altra soluzione che mi piace di più rispetto alla soluzione con il metodo della classe. Non sono ancora felice di non poter ignorare il metodo vuoto init.

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

Stai aggiungendo altro codice alla tua classe oltre a ciò che viene mostrato qui? Perché mi sto chiedendo perché una sottoclasse sia addirittura necessaria. –

+0

@TomHarrington Suggeriresti qualcosa come un'estensione per NSError? – Jonathan

risposta

3

Dal NSError è immutabile, non c'è alcun motivo per creare più istanze degli stessi dati. Basta creare un unico, costante, esempio:

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

Se si dispone di una situazione che non è costante, allora è quasi sempre meglio di estendere piuttosto che sottoclasse NSError. Per esempio:

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

Questo tipo di estensione (come categoria) ha una lunga storia nel objC, ed è un buon motivo per portare a Swift (se non è possibile utilizzare facilmente enum ErrorTypes, che sono ancora meglio Swift).

In molti casi trovo ancora più semplice avere una funzione di primo livello per questo, piuttosto che estendere NSError. Per esempio:

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

(Personalmente io uso questi tipi di funzioni per tutto il tempo a Swift quando devo usare NSError In objC, ho usato tipicamente categorie su NSError Non certo perché ho cambiato, ma ci si sente di più.. naturale.)

+0

Molto utile e completo. Molte grazie! – Jonathan

3

Non è possibile sovrascrivere l'init vuoto, è contrassegnato come non disponibile, quindi non si dovrebbe essere in grado di fare nulla con esso.

Si ha un'altra soluzione se

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] 
     ) 
    } 
} 

non ho la prova, ma dovrebbe funzionare.

Dato che si utilizza swift 2.0, perché non si rende l'istanza conforme al tipo di errore anziché alla sottoclasse di NSError? Sarebbe più pulito e più idiomatico.