在 Swift returns 错误中对数组对象使用谓词

Using Predicates on Array Objects in Swift returns Error

当我使用谓词过滤自定义数组 Swift 类 时,出现错误:

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

如果我没记错的话这会在 Objective-C 中起作用。我的错误是什么?

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)

您的 Seed class 是否继承自 NSObject?

如果没有,这就是您将收到的消息。

解决方案:

class Seed: NSObject {
   ...

编辑: stklieme 是正确的 - 要使用 NSPredicate,您的对象的 class 需要实现 NSKeyValueCoding protocol 定义的 -valueForKey。您可以定义您自己的 -valueForKey 实现,或者让您的 class 继承自 NSObject,它会为您处理。

这是在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.

valueForKey是一种键值编码方式。将 class 种子声明为符合 KVC

的 NSObject 的子class

简单地说,

您需要通过 NSObject 继承您的模型 class 并且您的问题得到解决。

class Seed: NSObject {
   ...
}

原因: -valueForKey 由 NSKeyValueCoding 协议定义。您可以定义自己的 -valueForKey 实现,或者让您的 class 继承自 NSObject

如果不想继承NSObject,可以自己实现value(forKey key: String) -> Any?方法:

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

注意方法的 @objc 前缀:这很重要,因为它允许 NSPredicate 看到方法已实现。如果没有它,您仍然会收到 does not implement methodSignatureForSelector: 崩溃。

或者,更好的是,使您的对象符合此协议:

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