2014-09-09 14 views
9

Sto cercando di utilizzare il protocollo NSCoding su una classe che ho scritto in rapida, ma non riesco a capire perché il compilatore si lamenta che "non è conforme al protocollo NSCoding" quando non implementare i metodi richiesti:Swift: non è conforme al protocollo NSCoding

class ServerInfo: NSObject, NSCoding { 

    var username = "" 
    var password = "" 
    var domain = "" 
    var location = "" 
    var serverFQDN = "" 
    var serverID = "" 

    override init() { 

    } 

    init(coder aDecoder: NSCoder!) { 
     self.username = aDecoder.decodeObjectForKey("username") as NSString 
     self.password = aDecoder.decodeObjectForKey("password") as NSString 
     self.domain = aDecoder.decodeObjectForKey("domain") as NSString 
     self.location = aDecoder.decodeObjectForKey("location") as NSString 
     self.serverFQDN = aDecoder.decodeObjectForKey("serverFQDN") as NSString 
     self.serverID = aDecoder.decodeObjectForKey("serverID") as NSString 
    } 


    func encodeWithCoder(_aCoder: NSCoder!) { 
     _aCoder.encodeObject(self.username, forKey: "username") 
     _aCoder.encodeObject(self.password, forKey: "password") 
     _aCoder.encodeObject(self.domain, forKey: "domain") 
     _aCoder.encodeObject(self.location, forKey: "location") 
     _aCoder.encodeObject(self.serverFQDN, forKey: "serverFQDN") 
     _aCoder.encodeObject(self.serverID, forKey: "serverID") 
    } 

} 

Si tratta di un bug o sto solo perdendo qualcosa?

risposta

17

Come si può vedere nei messaggi del compilatore descritti nel rapporto di navigatore, i metodi non sono dichiarati in modo corretto:

 
error: type 'ServerInfo' does not conform to protocol 'NSCoding' 
class ServerInfo: NSObject, NSCoding { 
^ 
Foundation.NSCoding:2:32: note: protocol requires function 'encodeWithCoder' with type '(NSCoder) -> Void' 
    @objc(encodeWithCoder:) func encodeWithCoder(aCoder: NSCoder) 
          ^
note: candidate has non-matching type '(NSCoder!) ->()' 
    func encodeWithCoder(_aCoder: NSCoder!) { 
     ^
Foundation.NSCoding:3:25: note: protocol requires initializer 'init(coder:)' with type '(coder: NSCoder)' 
    @objc(initWithCoder:) init(coder aDecoder: NSCoder) 
         ^
note: candidate has non-matching type '(coder: NSCoder!)' 
    init(coder aDecoder: NSCoder!) { 

(. Questo può essere cambiato tra le versioni beta) Inoltre, il initWithCoder metodo deve essere contrassegnato come required:

required init(coder aDecoder: NSCoder) { } 

func encodeWithCoder(_aCoder: NSCoder) { } 

In Swift 3 i metodi necessari sono

required init(coder aDecoder: NSCoder) { } 

func encode(with aCoder: NSCoder) { } 
+2

"Questo potrebbe essere cambiato fra le release beta" Sì, uno vuole urlare a Swift, "Amico, ho ottenuto queste firme metodo _dal voi! _ Come osi dirmi che ora si sbagliano ?! " Ma naturalmente questa è la vita nella veloce corsia beta ... – matt

+0

@matt: Almeno il compilatore stampa qui un messaggio ragionevole, invece di * "$% §? & Non può essere convertito in UInt8" * :) –

+0

Tranne che metà del tempo in cui il parametro si lamenta è sbagliato! :)) – matt

4

I parametri non sono implicitamente da scartare, e l'inizializzazione richiede l'required modificatore (rimuovere il!):

required init(coder aDecoder: NSCoder) { 
... 
func encodeWithCoder(_aCoder: NSCoder) { 

Per Swift 3

Un cambiamento minore, ma importante è stato commesso. Il metodo init è lo stesso, ma il metodo encodeWithCoder è stato modificato.

required init(coder aDecoder: NSCoder) { 
    ... 
    } 

    func encode(with _aCoder: NSCoder) { 
    ... 
    } 
0

Per Swift 3 (su Xcode 8.2 beta (8C23))

sembra avere cambiato di nuovo. Questa è l'unica variazione che ho potuto ottenere a lavorare ...

func encodeWithCoder(_ _aCoder: NSCoder) { 
    ... 
} 
Problemi correlati