2017-09-22 1 views
3

Swift에서 NSPredicate를 사용하여 배열을 필터링하고 있습니다. 문제는 iOS 11 (Xcode 9/w Swift 4)으로 업데이트 한 후입니다. 필터 라인에서 충돌이 계속 발생합니다. > '[valueForUndefinedKey :] :.이 클래스는 키가 아닌> 코딩 호환 키 이름 값'응용 프로그램을 종료Swift 배열 충돌에 대한 iOS 11 NSPredicate 검색 - NSUnknownKeyException

인해 캐치되지 않는 예외 'NSUnknownKeyException', 이유에 대한 다음은 충돌 로그입니다

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

질문은 왜 지금 충돌한다 : 여기

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

가 충돌되는 코드입니다 : 여기

내가의 배열을 가지고있는 클래스의 예입니다 iOS 11으로 업데이트 되었습니까?

답변

7

잠시 동안 이걸로 싸운 후, 나는 결국 대답을 발견했습니다!

Swift 4로 업데이트하는 것은 NSObject의 서브 클래스 인 클래스가 더 이상 객관적인 -c에 노출되지 않았 음을 의미합니다. 이 때문에 클래스/함수에 @objc를 명시 적으로 추가해야합니다. 컴파일러는 주석이 필요한 장소를 알려주지 만 여기서는 그렇지 않습니다.

궁극적으로 이것 때문에 키 - 값 조회가 NSPredicate로 필터링하는 데 필요한 objective-c에 더 이상 암묵적으로 노출되지 않았습니다. 아래 코드는 충돌을 수정합니다!

해결 방법 1 개

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

솔루션 Uros19 2

대체 감사 대신 위의 기능을 구현, 당신은 @objc (예를 들어, @objc let name: String)와 속성에 직접 주석을 달 수 있습니다. @objc를 사용하여 속성에 주석을 추가하는 이유에 대해 약간의 명확성을 잃지 만 이는 단지 작은 고려 사항입니다.

저는이 사람들이 시간과 좌절을 덜어주기를 바랍니다.

+1

감사합니다. 누군가가 술어에 사용되는 속성이 더 많은 모델을 가지고 있고 (내가했던 것처럼)이 문제를 얻는 경우. 속성 선언 전에 @objc를 추가하면됩니다. 예를 들어,'@objc var name : String'과 같이, 긴 switch-case를 피할 수 있습니다. – Uros19

+0

니스, 나는 이것을 나의 대답에 추가 할 것이다! 감사. 이 방법으로 문제를 해결할 때 고려해야 할 사항은 '@ objc'로 속성에 직접 주석을 추가하는 이유에 대해 약간의 명료성을 잃어 버리는 것입니다. –