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

时间:2011-08-15 05:18:25

标签: iphone objective-c cocoa-touch core-data 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'

我所做的是通过调用[[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对象以便找出对象的类型。有人有什么建议吗?

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

  • 向其发送有问题的选择器的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 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

1 个答案:

答案 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除了导致问题之外在谓词中完全没有任何作用,所以我会失去它。

当你说:

时BTW
  

我所做的是通过调用

使用Core Data从sqLite加载数据

...这表明您正在考虑将Core Data作为sqlite的对象包装器。它不是并且认为这样会让你遇到麻烦特别是与谓词。