How do I set up a NSPredicate to look for objects that have a nil attribute

Objective CNspredicate

Objective C Problem Overview


I have a ManagedObject class, and one of the members of the class is a NSDate. I would like to display all objects of the class for which the date is NOT set. I tried using a predicate like this:

NSPredicate *predicate = [NSPredicate predicateWithFormat: @"(date = NIL)"];

But I still get objects where the date is set. What is the right way to set up a predicate for this?

Objective C Solutions


Solution 1 - Objective C

I think it's a case sensitivity issue. You can use "nil" or "NULL", but not "NIL". This works fine for me:

NSPredicate *eventWithNoEndDate = [NSPredicate predicateWithFormat:@"endDate = nil"];

Solution 2 - Objective C

Figured it out. Couldn't do it by using a predicate with a string format, so tried a predicate with a template and it worked. Here's the code that gave me objects that had endDate set to NULL:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"endDate = $DATE"];
predicate = [predicate predicateWithSubstitutionVariables:
                   [NSDictionary  dictionaryWithObject:[NSNull null] forKey: @"DATE"]];

Solution 3 - Objective C

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Predicates/Articles/pUsing.html#//apple_ref/doc/uid/TP40001794-SW4

following code should work

predicate = [NSPredicate predicateWithFormat:@"firstName = nil"];

Solution 4 - Objective C

There's a super annoying behavior of fetch requests, as documented by Apple:

> If an object in a context has been modified, a predicate is evaluated against its modified state, not against the current state in the persistent store. Therefore, if an object in a context has been modified such that it meets the fetch request’s criteria, the request retrieves it even if changes have not been saved to the store and the values in the store are such that it does not meet the criteria. Conversely, if an object in a context has been modified such that it does not match the fetch request, the fetch request will not retrieve it even if the version in the store does match.

It's possible you're clearing the date elsewhere and the fetch request is including results where the date is nil in memory but still set on disk (in the persistent store), and so when the object faults it loads the object with the date set.

My only advice would be to coordinate access to the managed object context (say, on an NSOperationQueue) such that any updates are able to be saved to the persistent store before executing the fetch request.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmezuluView Question on Stackoverflow
Solution 1 - Objective CChristopher PickslayView Answer on Stackoverflow
Solution 2 - Objective CmezuluView Answer on Stackoverflow
Solution 3 - Objective CJerry JuangView Answer on Stackoverflow
Solution 4 - Objective CFrank SchmittView Answer on Stackoverflow