2014-06-13 16 views
10

Sto riscrivendo una categoria di Objective C al di sotto di Swift:Manipolazione Errore di inizializzazione di classe in estensione Swift

@implementation UIImage (Extra) 

+ (UIImage *)validImageNamed:(NSString *)name 
{ 
    UIImage *image = [self imageNamed:name]; 
    NSAssert(image, @"Unable to find image named '%@'", name); 
    return image; 
} 

Questo chiede di essere implementato come un init convenienza, ma come posso controllare se designato inizializzatore self.init (nome :) succede?

extension UIImage { 
    convenience init(validateAndLoad name: String!) { 
     self.init(named: name) 

     // need to assert here if self.init fails 
    } 

Quando self.init (dal nome :) chiamata non riesce, init di estensione interrompe l'esecuzione.

Ho provato a creare un'istanza UIImage e assegnarlo a sé, ma questo non viene compilato.

Naturalmente, un metodo di supporto può essere utilizzato come nella versione objC:

extension UIImage { 

    class func validImage(named name: String) -> UIImage { 
     var image = UIImage(named: name) 
     assert(image == nil, "Image doesn't exist") 
     return image 
    } 

Ma c'è un modo per implementare questo utilizzando un inizializzatore?

risposta

7

È ora possibile creare failable initializers nelle estensioni; tuttavia, gli inizializzatori non possono essere definiti in un protocollo.

class Thing { 

    var text:String? 

} 

extension Thing { 

    convenience init?(text:String) { 
     self.init() 
     if text == "" { 
      return nil 
     } else { 
      self.text = text 
     } 
    } 
} 


let that = Thing(text: "Hello") 
println(that?.text) //prints Optional("Hello") 

let empty = Thing(text: "") 
println(empty) //prints nil 
0

vorrei scrivere il metodo come di seguito:

extension UIImage { 

class func validImage(named name: String) -> UIImage? { 
    var image = UIImage(named: name) 
    return image 
} 

in rapida è possibile utilizzare optionals. Se qui non c'è immagine con il nome dato, il metodo restituirà zero.

3

A differenza di Objective-C, gli inizializzatori Swift non restituiscono l'auto, quindi non è possibile verificare la presenza di errori di inizializzazione. Un Apple engineer suggested utilizzando un metodo factory con un tipo di ritorno opzionale invece:

class ImageFactory { 

    class func validImage(named name: String) -> UIImage? 
    { 
     var image = UIImage(named:name) 
     assert(image != nil, "fail") 
     return image; 
    } 
} 

L'ingegnere di Apple ha indicato che stanno lavorando sulla costruzione di qualcosa nella lingua che andare in giro usando i metodi della classe di fabbrica.

+2

Perché restituire un optional se la funzione è progettata per non restituire mai 'nil'? – nschum

Problemi correlati