web-dev-qa-db-ja.com

NSPredicate-ブール値に基づいて値をフィルタリング

Entryというコアデータモデルオブジェクトがあります。これには、IsFavoriteという属性があります。

NSPredicateを使用して、NSFetchedResultsControllerの結果をフィルタリングしたいと思います。

現在、フェッチの実行時にEXC_BAD_ACCESSを取得しています。

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate. 

NSEntityDescription *thisEntry = [NSEntityDescription entityForName:@"Entry" inManagedObjectContext:managedObjectContext_];
[fetchRequest setEntity:thisEntry];

NSPredicate *fetchPredicate = [NSPredicate predicateWithFormat:@"Entry.isFavorite == %@", [NSNumber numberWithBool: YES]];

[fetchRequest setPredicate:predicate];


NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Root"];
aFetchedResultsController.delegate = self;


NSError *error = nil;
if (![aFetchedResultsController performFetch:&error]) {
    NSlog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}

FetchRequestの述語を設定する行を削除すると、コードは完全に実行されます。

私は明らかに述語でn00binを使用していますが、コアデータモデルオブジェクトからBOOLEAN値の操作を実行する方法を見つけるのに多くの問題がありました。文字列または整数値を使用してこれを行う方法についての回答はありますが、ブールの例は見つかりません。

どうもありがとう !

34
Lance

これはNSPredicateに固有のものではありません...書式文字列に%@がある場合、対応する値はオブジェクトへのポインタでなければならず、BOOLは修飾されません。したがって、YESを渡す代わりに、[NSNumber numberWithBool: YES]を渡します。


最初に回答を書いたときよりも新しいバージョンのXcodeとSDKでは、@YESの代わりに[NSNumber numberWithBool: YES]を使用できます。

42
JWWalker

Appleのドキュメントから:

ブール値

次の例に示すように、ブール値が等しいかどうかを指定してテストします。

NSPredicate *newPredicate =
    [NSPredicate predicateWithFormat:@"anAttribute == %@", [NSNumber numberWithBool:aBool]];
NSPredicate *testForTrue =
    [NSPredicate predicateWithFormat:@"anAttribute == YES"];

しかし、私を引き付けた何か:

必ずOptionalエンティティ属性のチェックを外し、Default ValueYESまたはNOに設定してください。そうしないと、列が空(null?)になり、上記の述語になります。明示的に設定されていない行とは一致しません。

結果のシミュレーター・データベースを調べて、素晴らしいアプリsqllitebrowserを使用してこれを診断しました。

32
scipilot

YESを探していることがわかっている場合(したがって、さまざまな状況でYESとNOを切り替える必要はありません)、これは私にとってうまくいきました:

[NSPredicate predicateWithFormat:@"isFavorite == 1"]
25
wrees

Swift 3バージョンは私にとってうまくいきました:

 let predicate = NSPredicate(format: "isFriend == %@" ,NSNumber(booleanLiteral: false))

@scipilotの回答に続いて、ブール値はオプションであってはなりません。それをありがとう!

2
Rotem Doron

私にとっては、Swift 3. NSNumberを使用し、%@が機能しなかったため、整数値を使用する必要がありました。

NSPredicate(format: "yourAttributeName == %i", yourBooleanValue ? 1 : 0)
1
pierre23

興味深いことに、どちらが必要かを「知っている」場合は、次のようにすることができます。

let p = NSPredicate(format: "showMe == true")

例、

let r = NSFetchRequest<NSFetchRequestResult>(entityName: "CDThing")
let p = NSPredicate(format: "showMe == true")
r.predicate = p

「サブスクライブ」、「新規」などの場合にこれを行います。

1
Fattie

iOS 10、xcode 9.0では、ブールNO属性を持つコアデータmanagedObjectを探します。

[NSPredicate predicateWithFormat:@"attributeName == nil"]
0