2014-09-30 19 views
25

Sto utilizzando con successo il metodo setValue(value, forKey: key) nella sottoclasse Swift NSObject compatibile con NSKeyValueCoding.Utilizzo di setValue (valore, forKey: chiave) su Int? tipi attiva metodo di codifica senza valore chiave

Ciò funziona perfettamente su opzioni di stringa, ad es.

var name:String? 

Tuttavia, in optional Int, viene a mancare, innescando il metodo chiave indefinita che ho ignorato per il debugging:

override func setValue(value: AnyObject!, forUndefinedKey key: String!) { 
    println("\(self) this class is not key value coding-compliant for the key \(key)") 
} 

Così, per esempio, una chiave di myId con un buon valore intero sarebbe attivare il metodo chiave non definito sopra.

var myId:Int? 

Se cambio la definizione di cui sopra per essere non-optional, poi tutto funziona bene:

var myId:Int = 0 

Con myId come optional, ho provato assolutamente tutto quello che mi viene in mente nel modo di casting, unwrapping, inizializzazione e così via. Semplicemente non vede la classe come valore chiave compatibile per quei valori numerici.

So che è un buon valore numerico. Cambiando la dichiarazione var in stringa? si blocca. Sembra anche bene in lldb:

Printing description of key: 
myId 
key NSObject 0x00007fb8d530ca20 0x00007fb8d530ca20 
k NSString "myId" 0x00007fa2aa942f20 
value __NSCFNumber * Int64(4348129) 0xb000000004258e13 
Printing description of value: 
4348129 
(lldb) 

Quindi, la domanda è, qualcuno ha utilizzato - a Swift - il metodo NSKeyValueCoding setValue(value, forKey: key)su un tipo Int successo?

+1

Questo potrebbe essere dovuto al fatto Int è di tipo Qualsiasi e non ANYOBJECT. Ho provato l'analisi di un oggetto in un dizionario e ritorno e ho avuto problemi simili. Vedere https://github.com/evermeer/EVCloudKitDao/blob/master/AppMessage/AppMessage/CloudKit/EVReflection.swift Si può vedere che ho provato ad analizzare Any to a AnyObject. I valori Nullable sono ancora un problema, ma funziona su un Int. –

risposta

24

KVO non può funzionare con gli optionals Swift puri perché gli optionals di Swift non sono oggetti Objective-C. Swift vieta l'uso di dynamic o @objc con classi e strutture generiche perché non esiste alcun equivalente Objective-C valido, e quindi il runtime non è configurato per supportare KVO su istanze di questi tipi di oggetti. Per quanto riguarda il motivo per cui funziona con String?, quel tipo è senza ponticelli ponticellato su NSString, quindi è semanticamente equivalente a NSString *, un tipo Objective-C che il runtime sa bene come gestire. Ma confronta quello a Int? il cui equivalente semantico sarebbe Optional<Int>, non UnsafePointer<Int> o NSNumber * come ci si potrebbe aspettare. Per ora, dovrai convincere il typechecker che è sicuro rappresentare in Objective-C usando NSNumber!.

Questo è completamente indietro e, a mio parere, una sfortunata limitazione del sistema di tipi. Per tutti gli ingegneri che si imbattono in questo post, vedere rdar: // 18624182.

+1

Penso che ci siano alcune inesattezze tecniche in questo post. 1) Ho cambiato 'Int?' In 'NSNumber?', E ora è completamente compatibile con KVO.2) KVO può funzionare con optionals, dato che posso usare 'UIColor?', 'NSNumber?', E altri tipi di objc. 3) Gli optionals sono generici appositamente gestiti e persino aggiunti a Objc usando 'nonnullable',' nullable', ecc. – Mazyod

+0

1 è implicito nella frase finale del primo paragrafo, 2 nella 3a frase e 3 è errata. Gli optionals sono collegati a un set limitato di tipi ObjC dal runtime, ma non sono completamente rappresentabili con solo i nuovi attributi nullable. Inoltre, si tratta di strutture Swift e KVO, non di strutture Objective-C collegate. – CodaFi

3

Se siete disposti a scavare tipi Swift cambia:

var myId:Int? 

a:

var myId:NSNumber?