2015-06-25 32 views
6

Quando ho filtrare una serie di classi Swift personalizzato utilizzando un predicato ottengo l'errore:Uso Predicati su array oggetti a Swift restituisce l'errore

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

Se non ricordo male questo funzionerebbe in Objective-C. Qual è il mio errore?

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) 

risposta

12

La classe Seed eredita da NSObject?

In caso contrario, questo è il messaggio che otterrete.

Soluzione:

class Seed: NSObject { 
    ... 

Edit: stklieme è corretta - di utilizzare NSPredicate, la classe del vostro oggetto deve implementare -valueForKey come definito dal NSKeyValueCoding protocol. È possibile definire la propria implementazione di -valueForKey o semplicemente ereditare la classe da NSObject che si occupa di ciò per voi.

Questo è definito in 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

No, non è così ... Come si può suppone di sapere che ... –

+1

fatto qualche modifiche, vuol spiegare è meglio? È proprio il modo in cui NSPredicate funziona internamente per convertire una stringa in una chiave che può essere utilizzata per ottenere un valore dall'istanza della classe. – jperl

1

valueForKey è un metodo valore della chiave di codifica. Dichiarare il Seme classe come una sottoclasse di NSObject conforme alle KVC

+1

Hai bisogno di KVC per questa sintassi del predicato, ma non hai bisogno di KVO. KVO pone requisiti aggiuntivi per una classe che non sono rilevanti qui. – Rob

0

Semplicemente,

È necessario ereditare la classe del modello da NSObject e il problema ottenere fisso.

class Seed: NSObject { 
    ... 
} 

Motivo: -valueForKey come definito dal protocollo NSKeyValueCoding. È possibile definire la propria implementazione di -valueForKey, o semplicemente rendere la vostra eredita dalla classe NSObject

1

Nel caso in cui se non si vuole ereditare da NSObject, è possibile implementare value(forKey key: String) -> Any? metodo da soli:

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

Nota @objc prefisso del metodo: è importante, in quanto consente a NSPredicate di verificare che il metodo sia implementato. Riceverai comunque does not implement methodSignatureForSelector: crash senza di esso.

O, meglio ancora, fare i vostri oggetti di conformarsi questo protocollo:

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