Sometimes I got error saying that unrecognized selector objcType was sent to an NSDate object:
2011-06-11 14:44:51.589 MyApp[354:307] -[__NSDate objCType]:
unrecognized selector sent to instance 0x4b0d5a02011-06-11 14:44:51.732 MyApp[354:307] * Terminating app due to
uncaught exception ‘NSInvalidArgumentException’, reason: ‘-[__NSDate
objCType]: unrecognized selector sent to instance 0x4b0d5a0’
What I do is loading data from sqLite using Core Data by calling [[self fetchedResultsController] performFetch:&error]. I use a predicate, which ensures that the only (NSManaged)objects having their attribute kickoffTime of type NSDate in a specified range are fetched:
NSDate * fromDate = ...
NSDate * toDate = ...
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"( ( %@ <= kickoffTime +0 ) && ( kickoffTime +0 <= %@ ) )", fromDate, toDate];
// Add the predicate to the fetchRequest
[[[self fetchedResultsController] fetchRequest] setPredicate:predicate];
NSError *error;
if (![[self fetchedResultsController] performFetch:&error])
{
...
}
I do not really know what the problem might be. I probably misuse the core data predicate in some way, forcing the framework to send the objCType message to NSDate object in order to find out type of the object. Does anybody have some suggestions?
Here is a few things I have observed:
- the NSDate object to which is sent the problematic selector is the kickoffTime attribute of my NSManagedObject
- it happens pretty randomly so it is not easy to reproduce
- the NSDate object to which the unrecognized selector is sent appears to be valid object (I could print it out in gdb)
Here is the top of the stack:
0 CoreFoundation 0x3587a987
__exceptionPreprocess + 1141 libobjc.A.dylib 0x34a8249d
objc_exception_throw + 242 CoreFoundation 0x3587c133
-[NSObject(NSObject) doesNotRecognizeSelector:] + 1023 CoreFoundation 0x35823aa9 forwarding +
5084 CoreFoundation 0x35823860
_CF_forwarding_prep_0 + 485 Foundation 0x3121ac69
+[_NSPredicateUtilities add:to:] + 406 Foundation 0x31221225
-[NSFunctionExpression expressionValueWithObject:context:] + 6887 Foundation 0x3117e045
-[NSComparisonPredicate evaluateWithObject:substitutionVariables:] +
1768 Foundation 0x312255fb
-[NSCompoundPredicateOperator
evaluatePredicates:withObject:substitutionVariables:] + 1869 Foundation 0x3121e43f
-[NSCompoundPredicate evaluateWithObject:substitutionVariables:] + 18610 Foundation 0x3117df8d -[NSPredicate
evaluateWithObject:] + 1611 CoreData 0x356e8edf
-[NSManagedObjectContext executeFetchRequest:error:] + 201412 CoreData 0x357a041b
-[NSFetchedResultsController performFetch:] + 76613 MyApp 0x000195ef
-[MatchesCalendarDataSource loadMatchesFrom:to:delegate:] + 138
The
objcTypeis a selector/method of NSValue and its subclasses like NSNumber. That means that the NSDate object is being treated like a NSValue at some point. It most likely happens when the NSDate is being wedged into a mathematical operation which it doesn’t support.In a predicate, a NSDate will often be converted to a NSTimeInterval which is a double. If you log the predicate you have above, the date will resolve something like this:
… which is the NSDate being cast to a double. That is where your problem comes from. I suspect it arises because the predicate parser cannot always resolve the precedence.
You can probably resolve the problem just by:
However, the
+0does absolutely nothing in a predicate besides cause problems so I would just lose it.BTW when you say:
… that suggest that you are thinking of Core Data as an object wrapper for sqlite. It isn’t and thinking that way will get you into trouble especially with predicates.