2014-09-30 14 views
25

Ich verwende erfolgreich die setValue(value, forKey: key) Methode in meiner NSKeyValueCoding-kompatiblen Swift NSObject-Unterklasse.Verwenden von SetValue (Wert, forKey: Schlüssel) auf Int? Typen feuert Nicht-Schlüsselwert Kodierung-konforme Methode

Dies funktioniert perfekt auf String Optionen, z.

var name:String? 

jedoch auf optionals Int, es scheitert, die undefinierte Schlüsselmethode Auslösung, die ich für Debug-Zwecke außer Kraft gesetzt habe:

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

So zum Beispiel eines Schlüssel von myId mit einem guten ganzzahligen Wert würde triggern Sie die oben beschriebene undefinierte Schlüsselmethode.

var myId:Int? 

Wenn ich die obige Definition ändere nicht optional sein, dann funktioniert alles einwandfrei:

var myId:Int = 0 

Mit myId als optionalen, ich habe absolut alles versucht, ich in der Art und Weise denken kann, Casting, Unpacking, Initialisierung, und so weiter. Es sieht die Klasse nicht als Schlüsselwert für diese numerischen Werte.

Ich weiß, dass es ein guter numerischer Wert ist. Ändern der var-Deklaration in String? stürzt ab. Es sieht auch gut 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) 

So wird die Frage, hat jemand verwendet - in Swift - die NSKeyValueCoding Methode setValue(value, forKey: key)auf einen Int-Typ erfolgreich?

+1

Könnte dies sein, weil Int beliebigen Typ und nicht ANYOBJECT ist. Ich habe versucht, ein Objekt zu einem Wörterbuch und zurück zu analysieren und hatte ähnliche Probleme. Siehe https://github.com/evermeer/EVCloudKitDao/blob/master/AppMessage/AppMessage/CloudKit/EVReflection.swift Sie können sehen, dass ich versucht habe, Any zu AnyObject zu analysieren. Nullable-Werte sind immer noch ein Problem, aber es funktioniert auf einem Int. –

Antwort

24

KVO kann nicht mit reinen Swift-Optionen funktionieren, da reine Swift-Optionen keine Objective-C-Objekte sind. Swift verbietet die Verwendung von dynamic oder @objc mit generischen Klassen und Strukturen, da es kein gültiges Objective-C-Äquivalent gibt, und daher ist die Laufzeitumgebung nicht so eingerichtet, dass sie KVO für Instanzen dieser Art von Objekten unterstützt. Warum funktioniert es mit String?, ist dieser Typ gebührenfrei überbrückt zu NSString, so ist es semantisch äquivalent zu NSString *, ein Objective-C-Typ, den die Laufzeit weiß, wie man damit umgeht. Aber vergleichen Sie das mit Int?, deren semantisches Äquivalent wäre Optional<Int>, nicht UnsafePointer<Int> oder NSNumber * wie Sie vielleicht erwarten würden. Im Moment müssen Sie den Typchecker davon überzeugen, dass er in Objective-C unter Verwendung von NSNumber! sicher darzustellen ist.

Das ist komplett rückwärts und meiner Meinung nach eine unglückliche Einschränkung des Typsystems. Weitere Informationen zu Ingenieuren, die auf diesen Beitrag stoßen, finden Sie unter rdar: // 18624182.

+1

Ich denke, es gibt ein paar technische Ungenauigkeiten in diesem Beitrag. 1) Ich habe 'Int?' In 'NSNumber?' Geändert und jetzt ist es vollständig KVO-konform.2) KVO kann mit Optionals funktionieren, da ich 'UIColor?', 'NSNumber?' Und andere Objc-Typen verwenden kann. 3) Optionale sind speziell behandelte Generika und werden sogar zu Objc hinzugefügt, wobei "nicht nullable", "nullable", usw. verwendet werden. – Mazyod

+0

1 wird durch den letzten Satz des ersten Absatzes impliziert, 2 durch den dritten Satz, und 3 ist falsch. Optionale werden zu einer begrenzten Menge von ObjC-Typen durch die Laufzeit überbrückt, aber sie sind nicht nur mit den neuen Nullable-Attributen vollständig darstellbar. Dabei geht es um Swift-Strukturen und KVO, nicht um Objective-C-Strukturen. – CodaFi

3

Wenn Sie bereit sind, Swift Arten zu Graben ändern:

var myId:Int? 

zu:

var myId:NSNumber? 
Verwandte Themen