2014-09-30 21 views
25

Z powodzeniem używam metody setValue(value, forKey: key) w mojej podklasie Swift NSObject zgodnej z NSKeyValueCoding.Korzystanie z setValue (value, forKey: key) na Int? typy uruchamia metodę niezgodną z kodowaniem kodu kluczowego

Działa to doskonale na urządzeniach typu String, np.

var name:String? 

Jednak na optionals int, to się nie powiedzie, wyzwalając niezdefiniowanej metody kluczową że mam przesłonić dla celów debugowania:

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

Tak na przykład klucz myId z dobrą wartość całkowitą by wywołaj niezdefiniowaną metodę klucza powyżej.

var myId:Int? 

Jeśli zmienić powyższą definicję, aby nie być opcjonalne, a następnie wszystko działa poprawnie:

var myId:Int = 0 

Z myId jako opcjonalny, próbowałem absolutnie wszystko mogę myśleć na drodze rzutowanie, rozpakowywanie, inicjowanie i tak dalej. Po prostu nie widzi klasy jako wartości kluczowej zgodnej z tymi wartościami liczbowymi.

Wiem, że jest to dobra wartość liczbowa. Zmiana deklaracji var na String? awarie. także wygląda to dobrze w 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) 

Więc pytanie jest, czy ktoś wykorzystane - w Swift - metoda NSKeyValueCoding setValue(value, forKey: key)na typ Int z powodzeniem?

+1

Może to być spowodowane Int jest typu Any i nie AnyObject. Próbowałem parsować obiekt do słownika iz powrotem i miałem podobne problemy. Zobacz https://github.com/evermeer/EVCloudKitDao/blob/master/AppMessage/AppMessage/CloudKit/EVReflection.swift Możesz zobaczyć, że próbowałem parsować Any na AnyObject. Wartości nulla są nadal problemem, ale działa na Int. –

Odpowiedz

24

KVO nie może działać z czystymi opcjami Swift, ponieważ czyste opcje Swift nie są obiektami Celu-C. Swift zabrania używania klas dynamic lub @objc z ogólnymi klasami i strukturami, ponieważ nie istnieje poprawny odpowiednik Objective-C, więc środowisko wykonawcze nie jest skonfigurowane do obsługi KVO w instancjach tego rodzaju obiektów. Jeśli chodzi o powód, dla którego działa on z String?, ten typ jest bezpłatny i połączony z NSString, więc jest semantycznie równoważny z NSString *, typem Objective-C, który środowisko wykonawcze wie doskonale, jak sobie z nim radzić. Ale porównaj to z Int?, którego semantycznym odpowiednikiem będzie Optional<Int>, a nie UnsafePointer<Int> lub NSNumber *, jak można się spodziewać. Na razie musisz przekonać typechecker, że bezpieczne jest reprezentowanie w Objective-C za pomocą NSNumber!.

Jest to całkowicie wstecz i, moim zdaniem, niefortunne ograniczenie systemu typu. Dla inżynierów, którzy natkną się na ten post, zobacz rdar: // 18624182.

+1

Myślę, że w tym poście jest kilka nieścisłości technicznych. 1) Zmieniłem 'Int?' Na 'NSNumber?', A teraz jest w pełni zgodne z KVO.2) KVO może działać z opcjami, ponieważ mogę używać 'UIColor?', 'NSNumber?' I innych typów obiektów. 3) Opcjonalne są specjalnie obsługiwane generyczne, a nawet dodawane do Objc przy użyciu "nieulotnej", 'nullable', .. itd. – Mazyod

+0

1 jest implikowane przez ostatnie zdanie pierwszego akapitu, 2 przez trzecie zdanie, a 3 jest błędne. Opcje są zmostkowane do ograniczonego zestawu typów ObjC przez środowisko wykonawcze, ale nie są one całkowicie reprezentowalne przy użyciu tylko nowych atrybutów zerujących. Poza tym chodzi o konstrukcje Swift i mosty w strukturach KVO, a nie Objective-C. – CodaFi

3

Jeśli jesteś gotów do rowu Swift rodzajów zmienić:

var myId:Int? 

do:

var myId:NSNumber?