[__NSDate objCType]:无法识别的选择器

ond*_*dra 2 iphone cocoa-touch core-data objective-c ios4

有时我得到错误,说无法识别的选择器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'

我所做的是通过调用使用Core Data从sqLite加载数据[[self fetchedResultsController] performFetch:&error].我使用谓词,它确保获取具有指定范围内kickoffTime类型属性的唯一(NSManaged)对象NSDate:

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]) 
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

我真的不知道问题可能是什么.我可能以某种方式滥用核心数据谓词,迫使框架将objCType消息发送到NSDate对象以便找出对象的类型.有人有什么建议吗?

以下是我观察到的一些事情:

  • 向有问题的选择器发送的NSDate对象是我的NSManagedObject的kickoffTime属性
  • 它是随机发生的,所以不容易重现
  • 发送无法识别的选择器的NSDate对象似乎是有效对象(我可以在gdb中打印出来)

这是堆栈的顶部:

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基础0x3121e43f - [NSCompoundPredicate evaluateWithObject:substitutionVariables:] + 186

10基础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

Tec*_*Zen 8

objcType是NSValue的选择器/方法及其子类,如NSNumber.这意味着NSDate对象在某些时候被视为NSValue.当NSDate被楔入它不支持的数学运算时,很可能发生这种情况.

在谓词中,NSDate通常会转换为NSTimeInterval,这是一个双精度数.如果您记录上面的谓词,日期将解析如下:

CAST(335110182.022141, "NSDate") <= kickoffTime + 0 AND kickoffTime + 0 <= CAST(335110182.022141, "NSDate")
Run Code Online (Sandbox Code Playgroud)

...这是NSDate被强制转换为双倍.这就是你的问题所在.我怀疑它的出现是因为谓词解析器无法始终解析优先级.

您可以通过以下方式解决问题:

(CAST(335110182.022141, "NSDate") <= kickoffTime + 0) AND (kickoffTime + 0 <= CAST(335110182.022141, "NSDate"))
Run Code Online (Sandbox Code Playgroud)

但是,+0除了导致问题之外,谓词中的任何内容都没有,所以我会失去它.

BTW当你说:

我所做的是通过调用使用Core Data从sqLite加载数据

...这表明您正在考虑将Core Data作为sqlite的对象包装器.它不是并且认为这种方式会让你陷入麻烦,特别是对于谓词.