2015-06-25 14 views
6

Kiedy filtrowanie tablicę klas niestandardowych Swift za pomocą predykatu pojawia się błąd:Korzystanie predykaty na Array obiektów w Swift zwraca błąd

*** NSForwarding: warning: object 0x78ed21a0 of class 'Plantivo1_6.Seed' does not implement methodSignatureForSelector: -- trouble ahead
Unrecognized selector -[Plantivo1_6.Seed valueForKey:]

Jeśli dobrze pamiętam to będzie działać w Objective-C. Jaki jest mój błąd?

let names = ["Tom","Mike","Marc"] 
println(names) 
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %@", "om") 
let array = (names as NSArray).filteredArrayUsingPredicate(searchPredicate) 
println(array) 
println() 

let mySeed1 = Seed() // Seed is a class with a `culture` String property 
let mySeed2 = Seed() 
let mySeed3 = Seed() 
mySeed1.culture = "Tom" 
mySeed2.culture = "Mike" 
mySeed3.culture = "Marc" 

let mySeeds = [mySeed1,mySeed2,mySeed3] 
println(mySeeds) 
let searchPredicate1 = NSPredicate(format: "SELF.culture CONTAINS[c] %@", "om") 
let array1 = (mySeeds as NSArray).filteredArrayUsingPredicate(searchPredicate1) 
println(array1) 

Odpowiedz

12

Czy twoja klasa Seed dziedziczy po NSObject?

Jeśli nie, jest to wiadomość, którą otrzymasz.

Rozwiązanie:

class Seed: NSObject { 
    ... 

Edit: stklieme jest poprawna - używać NSPredicate, klasa Twojego obiektu musi wdrożyć -valueForKey zdefiniowane przez NSKeyValueCoding protocol. Możesz zdefiniować własną implementację -valueForKey lub po prostu uczynić swoją klasę dziedziczącą po NSObject, która zajmuje się tym za Ciebie.

ta jest zdefiniowana w the Apple docs for NSPredicate,

You can use predicates with any class of object, but the class must support key-value coding for the keys you want to use in a predicate.

+1

Nie, to nie ... Jak ktoś ma wiedzieć, że ... –

+1

Wprowadzono kilka zmian, czy to wyjaśnić to lepiej? Tak właśnie działa NSPredicate wewnętrznie, aby przekonwertować ciąg znaków na klucz, który może być użyty do uzyskania wartości z instancji klasy. – jperl

1

valueForKey to metoda kodowania wartość klucza. Zadeklarować Seed klasy jako podklasy NSObject zgodnego KVC

+1

Potrzebujesz KVC dla tej składni predykatów, ale nie potrzebujesz KVO. KVO nakłada dodatkowe wymagania na klasę, które nie są tutaj istotne. – Rob

0

prostu

trzeba dziedziczą swoją klasę modelu przez NSObject i problemu dostać stałe.

class Seed: NSObject { 
    ... 
} 

Uzasadnienie: -valueForKey zdefiniowany przez protokół NSKeyValueCoding. Można też zdefiniować własną implementację -valueForKey, lub po prostu dokonać klasy Dziedziczy z NSObject

1

W przypadku jeśli nie chcą dziedziczyć NSObject, można zaimplementować value(forKey key: String) -> Any? sposób przez siebie:

extension Model { 
    @objc func value(forKey key: String) -> Any? { 
     switch key { 
     case "id": 
      return id 
     // Other fields 
     default: 
      return nil 
     } 
    } 
} 

Nuta @objc przedrostek metody: jest to ważne, ponieważ pozwala NSPredicate, aby zobaczyć, że metoda jest zaimplementowana. Ciągle otrzymasz awarię does not implement methodSignatureForSelector: bez tego.

Albo, jeszcze lepiej, tworzyć obiekty, które spełniają ten protokół:

@objc protocol UsableInPredicate { 
    @objc func value(forKey key: String) -> Any? 
}