本文介绍了iOS 11 NSPredicate搜索Swift阵列崩溃 - NSUnknownKeyException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用NSPredicate来过滤Swift中的数组。问题是在更新到iOS 11(Xcode 9 / w Swift 4)之后,我一直在过滤器线上崩溃。以下是崩溃日志:

I am using NSPredicate to filter an array in Swift. The problem is after updating to iOS 11 (Xcode 9 /w Swift 4), I keep getting a crash on the filter line. Here is the crash log:

以下是我有一个数组类的示例:

Here is an example of the class that I have an array of:

final class Model: NSObject {
    let name: String
    init(name: String) {
        self.name = name
    }
}

这是崩溃的代码:

let myArray = [Model(name: "Jason"), Model(name: "Brian")]
let predicate = NSPredicate(format: "name == 'Jason'")
let filteredArray = myArray.filter { predicate.evaluate(with: $0)}

问题是为什么我现在更新到iOS 11会崩溃?

Question is why is this crashing now that I updated to iOS 11?

推荐答案

经过一段时间的斗争,我终于遇到了答案呃!

After fighting with this for a while, I finally came across the answer!

更新到Swift 4的一个微妙之处在于,作为NSObject的子类的类不再像之前那样隐式地暴露给objective-c。因此,您需要使用@objc显式注释类/函数。编译器将通知您需要注释的位置,但不会在这种情况下通知您。

A subtlety of updating to Swift 4 is that classes that are subclasses of NSObject are no longer implicitly exposed to objective-c like they were before. Because of this, you need to explicitly annotate classes/functions with @objc. The compiler will notify you of places where the annotation is needed, but not in this case.

最终因此,键值查找不再隐式暴露给objective-c,需要使用NSPredicate进行过滤。以下代码修复了崩溃!

Ultimately because of this, the key-value lookup was no longer implicitly exposed to objective-c, which is needed to filter with NSPredicate. The code below fixes the crash!

解决方案1 ​​

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

解决方案2

替代感谢Uros19:您可以使用@objc直接注释属性,而不是实现上述函数(例如, @objc let name:String )。关于为什么要用@objc注释财产,你会失去一点清晰度,但这只是一个小问题。

Alternative thanks to Uros19: Instead of implementing the above function, you could annotate the property directly with @objc (e.g., @objc let name: String). You lose a little bit of clarity as to why you are annotating the property with @objc, but this is only a small consideration.

我希望这可以节省一些人的时间和沮丧:)

I hope this saves some people time and frustration :)

这篇关于iOS 11 NSPredicate搜索Swift阵列崩溃 - NSUnknownKeyException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-13 14:30