web-dev-qa-db-fra.com

NSPredicate - filtrage des valeurs en fonction d'une valeur stockée BOOLEAN

J'ai un objet de modèle de données principal appelé Entry . Dans celui-ci, j'ai un attribut IsFavorite.

Je voudrais utiliser un NSPredicate pour filtrer les résultats de mon NSFetchedResultsController.

J'obtiens actuellement EXC_BAD_ACCESS lorsque la récupération s'exécute.

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();
}

SI je supprime la ligne qui définit le prédicat sur fetchRequest, mon code s'exécute parfaitement.

Je suis clairement n00bin dehors sur le prédicat mais ai beaucoup de mal à essayer de savoir comment effectuer des opérations sur une valeur BOOLEAN à partir d'un objet de modèle de données principal Il est à noter qu'il existe des réponses sur la façon de procéder avec une chaîne ou une valeur int, mais je ne trouve pas d'exemple BOOLEN.

Merci beaucoup !

31
Lance

Ce n'est pas vraiment spécifique à NSPredicate ... Chaque fois que vous avez %@ dans une chaîne de format, la valeur correspondante doit être un pointeur sur un objet, et BOOL ne qualifie pas. Donc, au lieu de passer YES, passez [NSNumber numberWithBool: YES].


Dans les versions plus récentes de Xcode et des kits de développement logiciel (SDK) que lorsque j'avais écrit la réponse à l'origine, vous pouvez utiliser @YES au lieu de [NSNumber numberWithBool: YES].

41
JWWalker

De la documentation d'Apple:

Valeurs booléennes

Vous spécifiez et testez l'égalité des valeurs booléennes, comme illustré dans les exemples suivants:

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

Cependant, quelque chose qui m'a attiré dehors:

Assurez-vous de décocher l'attribut d'entité Optional et de définir un Default Value de YES ou NO, sinon la colonne sera vide (null?) Et les prédicats ci-dessus ne correspondront pas aux lignes qui ne sont pas définies explicitement.

J'ai utilisé l'excellente application sqllitebrowser pour diagnostiquer celle-ci, en consultant la base de données de simulateur résultante.

30
scipilot

Si vous savez que vous recherchez un OUI (et que vous n'avez donc pas besoin de basculer entre OUI ou NON dans différentes situations), cela a fonctionné pour moi:

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

La version 3 de Swift a très bien fonctionné pour moi: 

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

après @scipilot answer, la valeur booléenne ne devrait pas être une option. Merci pour ça!

2
Rotem Doron

Pour moi, sur Swift 3.0 use NSNumber et% @ ne fonctionnaient pas, je devais utiliser des valeurs entières: 

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

sur iOS 10, xcode 9.0, à la recherche d'un attribut core de données gérées avec un attribut booléen NON:

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