Core Data predicate falls when nil attribute

tl; dr: enter something here that won't happen if birthDate is zero:

xcdatamodel screenshot


I have an entity with the birthDate attribute and a derived property with the following predicate entered directly into the xcdatamodel file:

$FETCH_SOURCE.birthDate > birthDate 

This happily returns a list of managed entities older than FETCH_SOURCE (the managed entity in which the fetch request occurs). But BirthDate is optional, and if the date of birth for FETCH_SOURCE is zero ...

 Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'can't use NULL on left hand side' 

Note that this is great if the attribute is zero for the object being compared. If I change the arguments of the predicate:

 birthDate < $FETCH_SOURCE.birthDate 

... I get the same error. Trying to check it for zero:

 (birthDate != nil AND birthDate < $FETCH_SOURCE.birthDate) 

... gives ...

 'NSInvalidArgumentException', reason: 'illegal comparison with NULL' 

Google has not heard of any of these errors, so I think this is a recent state of affairs. The problem remains when String is being compared for equivalence or something else. Is there a way to fix this in the predicate so that it correctly returns an empty list? Thanks.

Change To be clear, the question is whether this failure can be fixed in the predicate in the xcdatamodel file.

Update: An accident occurs when a communication error for NSFetchedPropertyDescription starts, trying to read something about it, apparently because it does not try to run the predicate until then. However, this is not zero, and it can be checked for zero without fail.

+6
source share
2 answers

I cannot find any way to change the predicate of the selected property to avoid this error, but one way is to implement a custom getter for the olderHeroes fetched property. This should return an empty array if birthDate is zero.

 var olderHeroes: NSArray { var array : NSArray if self.birthDate == nil { array = NSArray() } else { self.willAccessValueForKey("olderHeroes") array = self.primitiveValueForKey("olderHeroes") as! NSArray self.didAccessValueForKey("olderHeroes") } return array } 

Or in Objective-C:

 -(NSArray *)olderHeroes { NSArray *array; if (self.birthDate == nil) { array = [NSArray array]; } else { [self willAccessValueForKey:@"olderHeroes"]; array = [self primitiveValueForKey:@"olderHeroes"]; [self didAccessValueForKey:@"olderHeroes"]; } return array; } 

(These fragments are included in the implementation file for a subclass of the FETCH_SOURCE object).

+6
source

If you want to have results containing either a nil value, or it must be greater or less than a certain date, use the following:

 ((birthDate == nil) OR (birthDate < %@)) 

This works for me. Hope this is what you are asking for. There were few problems understanding your question.

If you ask to check the variable that you pass in the predicate, perhaps the following work (untested):

 (($FETCH_SOURCE.birthDate == nil && birthDate == nil) OR ($FETCH_SOURCE.birthDate < birthDate)) 
+2
source

Source: https://habr.com/ru/post/989558/


All Articles