ある NSManagedObject のサブクラスが BOOL 型のプロパティ aBoolProperty
を持つとする。このプロパティが偽であるかどうかをテストするとき、以下のような NSPredicate を書きたくなるかもしれない:
anObject.aBoolProperty = NO;
NSPredicate *isNO = [NSPredicate predicateWithFormat:@"aBoolProperty == NO"];
[isNO evaluateWithObject:anObject]; // => YES
(注: predicate には比較演算子が必要なので @"!aBoolProperty"
とは書けない)
厳密に NO
と比較したいならこれで構わないが、 aBoolProperty
が 偽だが NO と一致しない 場合もあることに気をつけよう。
Core Data が内部的に扱う aBoolProperty
の値は @YES
または @NO
または nil
である。これは BOOL 型の getter メソッドを介してアクセスする限り問題にならないが、内部値を直接扱う predicate では nil != @NO
であることに注意しなければならない。
[anObject setPrimitiveValue:nil forKey:@"aBoolProperty"];
// getter は内部値が nil なら偽を返す
NSAssert(!anObject.aBoolProperty, @"");
// predicate では nil は NO と一致しない
NSPredicate *isNO = [NSPredicate predicateWithFormat:@"aBoolProperty == NO"];
[isNO evaluateWithObject:anObject]; // => *NO*
これが望み通りの挙動でないなら、 NO
と一致するかどうかではなく YES
でないことをテストすればよい:
[anObject setPrimitiveValue:nil forKey:@"aBoolProperty"];
NSPredicate *isNO = [NSPredicate predicateWithFormat:@"aBoolProperty != YES"];
[isNO evaluateWithObject:anObject]; // => YES