2017-09-22 9 views
3

Swiftの配列をフィルタリングするのにNSPredicateを使用しています。問題は、iOS 11(Xcode 9/w Swift 4)にアップデートした後です。私はフィルタラインでクラッシュし続けます。ここでクラッシュログは次のとおりです。キャッチされない例外により「NSUnknownKeyException」にアプリを終了iOS 11 Swift配列のクラッシュでのNSPredicate検索 - 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を明示的に注釈する必要があります。コンパイラは注釈が必要な場所を通知しますが、この場合は通知しません。

最終的にこれにより、Key-Valueルックアップは、NSPredicateでフィルタリングするために必要なobjective-cに暗黙的に公開されなくなりました。下のコードはクラッシュを修正しています! Uros19へ

ソリューション1

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

ソリューション2

代替感謝:代わりに、上記の機能を実装するので、あなたが@objc(例えば、@objc let name: String)と直接プロパティに注釈を付けることができます。あなたは@objcでプロパティに注釈を付ける理由について少し明確には分かりませんが、これはほんの少しの検討事項です。

私はこれがいくつかの人々の時間と欲求不満を節約したいと思っています:)

+1

ありがとうございます。誰かが述語に使用されるより多くのプロパティを持つモデルを持っていて、この問題を(私のように)得る。プロパティ宣言の前に@objcを追加することができます。たとえば '@objc var name:String'のように、長いスイッチケースを避けることができます。 – Uros19

+0

ニース、私はこれを私の答えに加えます!ありがとう。 このようにして問題を解決するには、プロパティに@ objcというアノテーションが直接付いている理由を少しはっきりさせる必要があります。 –

関連する問題