2017-09-22 99 views
3

我正在使用NSPredicate在Swift中過濾數組。問題是更新到iOS 11(Xcode 9/w Swift 4)之後,我不斷收到過濾器行的崩潰。這裏是崩潰日誌:iOS 11在Swift數組崩潰時進行Nspredicate搜索 - NSUnknownKeyException

終止應用程序由於未捕獲的異常「NSUnknownKeyException」,原因是:>「[valueForUndefinedKey:]:這個類是不鍵>值的鍵名順應編碼-」

下面是類的例子,我有一個數組:

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?

回答

7

經過這段時間的爭鬥,我終於遇到了答案!

更新到Swift 4的一個巧妙之處在於NSObject的子類不再像以前那樣隱式暴露給objective-c。因此,您需要使用@objc顯式註釋類/函數。編譯器會通知您需要註釋的地方,但在這種情況下不會。

最終因爲這個原因,鍵值查找不再隱式暴露給objective-c,而這需要使用NSPredicate進行過濾。下面的代碼修復了崩潰!

溶液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註釋該屬性會失去一點清晰度,但這只是一個小問題。

我希望這可以節省一些人的時間和無奈:)

+1

感謝您的支持。如果有人有更多的屬性用於謂詞並得到這個問題(像我一樣)。您可以在屬性聲明之前添加@objc。例如'@objc var name:String',這樣可以避免長時間切換。 – Uros19

+0

不錯,我會添加這個到我的答案!謝謝。 以這種方式解決問題的一個小問題是,爲了直接使用'@ objc'註釋屬性,您會失去一點清晰度。 –