조회where절에서 표기법 주의~NSPredicate 주의~[RealmSwift]
문제.
final class Page: Object {
@Persisted(primaryKey: true) var id = UUID().uuidString
@Persisted var title: String
@Persisted var isMarked = false
솔리드 정의가 있는 경우let pageList = List<Page>(...)
let searchText = "banana"
let results = pageList.where {
$0.isMarked
&& $0.title.contains(searchText, options: .caseInsensitive)
}
이런 검색어를 쓰면 실행 중 오류가 발생하여 욕을 먹는다.해결책
where
절에서 Bool
형 변수를 사용할 때 boolValue
를 사용하지 말고 boolValue == true
로 기술한다.즉, 위의 예에서
pageList.where {
$0.isMarked == true // ここ
&& $0.title.contains(searchText, options: .caseInsensitive)
}
이 맞습니다.까닭
각양각색의 실험을 통해 나는 이런 일을 알게 되었다.
where
섹션에 지정된 쿼리를 나타내는 클론이 실행되지 않음NSPredicate
의 문법으로 전환되고 NSPredicate
로 검증을 수행한다.where
절의 정의를 살펴보자.func `where`(_ isIncluded: ((Query<Element>) -> Query<Bool>)) -> Results<Element>
알고 있는 바와 같이 쿼리의 클론 유형은 ((Element) -> Bool)
이 아니라 ((Query<Element>) -> Query<Bool>))
입니다.이 일로 보아 흉계가 있는 것 같다.다음은 첫 번째로 소개한 오류 조회를 실행할 때의 오류 정보를 살펴보겠습니다.
Unable to parse the format string \"(isMarked && (title CONTAINS[c] %@))\"
내용이'해석불가NSPredicate
의 포맷 문자열'이기 때문에 NSPredicate
에서 나온 예외죠.그러나 쓴 코드에는 그런 것이 사용되지 않았다.따라서 조회의 복제는 어떤 방식으로 NSPredicate로 번역하는 것이 타당하다고 본다.조회의 컬렉션은 각 요소를 확인할 때마다 수행하는 것이 아니라 같은 의미NSPredicate
로 전환한 뒤 수행하는 것이다.Query
에 @dynamicMemberLookup
속성이 있기 때문에 안전하게 조회를 쓸 수 있습니다.조회에 적힌 $0.title
는 실제로Page
대상의 title
속성이 없습니다.$0.isMarked == true
와 $0.isMarked
두 가지 유형은 모두 일치성을 가지기 때문에 후자처럼 잘못된 문법도 컴파일할 수 있다.따라서 NSPredicate
전달된 표현이 문법으로서 정확하지 않아 실행할 때 오류가 발생할 수 있다.즉 컴파일러가 조회의 유형 안전을 보장했지만 문법의 타당성은 아직 보장되지 않았다는 것이다.이상의 일에 주의하면서 검색어를 쓰세요.
참고 문장
컨디션
Reference
이 문제에 관하여(조회where절에서 표기법 주의~NSPredicate 주의~[RealmSwift]), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/harumaru/articles/5f852c7c36697f텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)