2015-06-25 15 views
6

Wenn ich eine Reihe von benutzerdefinierten Swift Klassen filtern, um ein Prädikats ich mit dem Fehler:Verwendung von Prädikaten auf Array-Objekte in Swift gibt Fehler

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

Wenn ich mich richtig erinnere dies in Objective-C funktionieren würde. Was ist mein Fehler?

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) 

Antwort

12

Erbt Ihre Seed-Klasse von NSObject?

Wenn nicht, ist dies die Nachricht, die Sie erhalten werden.

Lösung:

class Seed: NSObject { 
    ... 

Edit: stklieme ist richtig - NSPredicate zu verwenden, muss Ihr Objekt der Klasse -valueForKey implementieren, wie durch die NSKeyValueCoding protocol definiert. Sie können entweder Ihre eigene Implementierung von -valueForKey definieren oder Ihre Klasse von NSObject erben lassen, die sich darum kümmern.

Diese in the Apple docs for NSPredicate definiert ist,

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

Nein, tut es nicht ... Wie man das wissen soll ... –

+1

einige Änderungen vorgenommen, wird das erklären es besser? Es ist nur die Art und Weise, wie NSPredate intern eine Zeichenfolge in einen Schlüssel konvertiert, der verwendet werden kann, um einen Wert von der Klasseninstanz zu erhalten. – jperl

1

valueForKey ist ein Schlüsselverfahren Kodierwert. Deklarieren Sie die Klasse Seed als eine Unterklasse von NSObject, die einfach

+1

Sie benötigen KVC für diese Prädikatsyntax, aber Sie benötigen KVO nicht. KVO stellt für eine Klasse zusätzliche Anforderungen, die hier nicht relevant sind. – Rob

0

zu KVC entspricht,

Sie benötigen eine Modellklasse von NSObject und Ihr Problem erben gefixt.

class Seed: NSObject { 
    ... 
} 

Grund: -valueForKey wie durch das Protokoll definiert NSKeyValueCoding. Sie können entweder eine eigene Implementierung von -valueForKey definieren, oder einfach nur von NSObject

1

Falls Ihre Klasse erben, wenn Sie von NSObject erben wollen nicht, Sie value(forKey key: String) -> Any? Methode selbst umsetzen können:

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

Hinweis @objc Präfix der Methode: Es ist wichtig, da es NSPredicate ermöglicht zu sehen, dass die Methode implementiert ist. Sie erhalten immer noch does not implement methodSignatureForSelector: Absturz ohne es.

Oder, noch besser, machen Sie Ihre Objekte dieses Protokoll entsprechen:

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