有时我收到错误消息称无法识别的选择器objcType
已发送到NSDate
对象:
2011-06-11 14:44:51.589 MyApp [354:307] - [__ NSDate objCType]: 无法识别的选择器发送到实例0x4b0d5a0
2011-06-11 14:44:51.732 MyApp [354:307] * 终止应用程序 未捕获的异常'NSInvalidArgumentException',原因:' - [__ NSDate objCType]:无法识别的选择器发送到实例0x4b0d5a0'
我所做的是通过调用[[self fetchedResultsController] performFetch:&error]
使用Core Data从sqLite加载数据。我使用谓词,它确保获取在指定范围内具有类型kickoffTime
的属性NSDate
的唯一(NSManaged)对象:
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])
{
...
}
我真的不知道问题可能是什么。我可能以某种方式滥用核心数据谓词,迫使框架将objCType
消息发送到NSDate对象以便找出对象的类型。有人有什么建议吗?
以下是我观察到的一些事情:
这是堆栈的顶部:
0 CoreFoundation 0x3587a987 __exceptionPreprocess + 114
1 libobjc.A.dylib 0x34a8249d objc_exception_throw + 24
2 CoreFoundation 0x3587c133 - [NSObject(NSObject)doesNotRecognizeSelector:] + 102
3 CoreFoundation 0x35823aa9 转发 + 508
4 CoreFoundation 0x35823860 _CF_forwarding_prep_0 + 48
5基金会0x3121ac69 + [_ NSPredicateUtilities add:to:] + 40
6基金会0x31221225 - [NSFunctionExpression expressionValueWithObject:context:] + 688
7基金会0x3117e045 - [NSComparisonPredicate evaluateWithObject:substitutionVariables:] + 176
8基金会0x312255fb - [NSCompoundPredicateOperator evaluatePredicates:withObject:substitutionVariables:] + 186
9 Foundation 0x3121e43f - [NSCompoundPredicate evaluateWithObject:substitutionVariables:] + 186
10 Foundation 0x3117df8d - [NSPredicate evaluateWithObject:] + 16
11 CoreData 0x356e8edf - [NSManagedObjectContext executeFetchRequest:error:] + 2014
12 CoreData 0x357a041b - [NSFetchedResultsController performFetch:] + 766
13 MyApp 0x000195ef - [MatchesCalendarDataSource loadMatchesFrom:to:delegate:] + 138
答案 0 :(得分:8)
objcType
是NSValue的选择器/方法及其子类,如NSNumber。这意味着NSDate对象在某些时候被视为NSValue。当NSDate被楔入它不支持的数学运算时,很可能发生这种情况。
在谓词中,NSDate通常会转换为NSTimeInterval,这是一个双精度数。如果您记录上面的谓词,则日期将解析如下:
CAST(335110182.022141, "NSDate") <= kickoffTime + 0 AND kickoffTime + 0 <= CAST(335110182.022141, "NSDate")
...这是NSDate被强制转换为double。这就是你的问题所在。我怀疑它的出现是因为谓词解析器无法始终解析优先级。
您可以通过以下方式解决问题:
(CAST(335110182.022141, "NSDate") <= kickoffTime + 0) AND (kickoffTime + 0 <= CAST(335110182.022141, "NSDate"))
然而,+0
除了导致问题之外在谓词中完全没有任何作用,所以我会失去它。
我所做的是通过调用
使用Core Data从sqLite加载数据
...这表明您正在考虑将Core Data作为sqlite的对象包装器。它不是并且认为这样会让你遇到麻烦特别是与谓词。