[__NSDate objCType]: нераспознанный селектор - PullRequest
2 голосов
/ 15 августа 2011

Иногда я получал сообщение о том, что нераспознанный селектор 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 '

Я загружаю данные из sqLite с использованием Core Data, вызывая [[self fetchedResultsController] performFetch:&error]. Я использую предикат, который обеспечивает выборку только (NSManaged) объектов, имеющих атрибут kickoffTime типа 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]) 
{
    ...
}

Я действительно не знаю, в чем может быть проблема. Я, вероятно, каким-то образом неправильно использую предикат базовых данных, заставляя инфраструктуру отправлять сообщение objCType объекту NSDate, чтобы выяснить тип объекта. У кого-нибудь есть предложения?

Вот несколько вещей, которые я наблюдал:

  • объект NSDate, на который отправляется проблемный селектор, является атрибутом kickoffTime моего NSManagedObject
  • это происходит довольно случайно, поэтому воспроизвести нелегко
  • объект NSDate, в который отправляется нераспознанный селектор, представляется действительным (я мог бы распечатать его в gdb)

Вот вершина стека:

0 CoreFoundation 0x3587a987 __exceptionPreprocess + 114

1 libobjc.A.dylib 0x34a8249d objc_exception_throw + 24

2 CoreFoundation 0x3587c133 - [NSObject (NSObject) делает NotRecognizeSelector:] + 102

3 CoreFoundation 0x35823aa9 пересылка + 508 * * тысячи сорок-пять

4 CoreFoundation 0x35823860 _CF_forwarding_prep_0 + 48

5 тональный крем 0x3121ac69 + [_ NSPredicateUtilities добавить: к:] + 40

6 тональный крем 0x31221225 - [NSFunctionExpression expressionValueWithObject: context:] + 688

7 Фонд 0x3117e045 - [NSComparisonPredicatevaluWithObject: substitutionVariables:] + 176

8 тональный крем 0x312255fb - [NSCompoundPredicateOperator оцениватьПредикаты: withObject: substitutionVariables:] + 186

9 Фонд 0x3121e43f - [NSCompoundPredicatevaluWithObject: substitutionVariables:] + 186

10 Foundation 0x3117df8d - [NSPredicate valuWithObject:] + 16

11 CoreData 0x356e8edf - [NSManagedObjectContext executeFetchRequest: ошибка:] + 2014

12 CoreData 0x357a041b - [NSFetchedResultsController executeFetch:] + 766

13 MyApp 0x000195ef - [MatchesCalendarDataSource loadMatchesFrom: to: делегат:] + 138

1 Ответ

8 голосов
/ 15 августа 2011

objcType - это селектор / метод NSValue и его подклассов, таких как NSNumber. Это означает, что в какой-то момент объект NSDate обрабатывается как NSValue. Скорее всего, это происходит, когда NSDate вклинивается в математическую операцию, которую он не поддерживает.

В предикате NSDate часто конвертируется в NSTimeInterval, который является двойным. Если вы зарегистрируете предикат, который у вас есть выше, дата разрешит что-то вроде этого:

CAST(335110182.022141, "NSDate") <= kickoffTime + 0 AND kickoffTime + 0 <= CAST(335110182.022141, "NSDate")

... это NSDate, который удваивается. Вот откуда твоя проблема. Я подозреваю, что это происходит потому, что анализатор предикатов не всегда может разрешить приоритет.

Вы можете решить проблему, просто:

(CAST(335110182.022141, "NSDate") <= kickoffTime + 0) AND (kickoffTime + 0 <= CAST(335110182.022141, "NSDate"))

Однако +0 абсолютно ничего не делает в предикате, кроме того, что вызывает проблемы, поэтому я бы просто потерял его.

Кстати, когда вы говорите:

Я загружаю данные из sqLite с помощью Core Data, вызывая

... это говорит о том, что вы думаете о Core Data как обёртке объекта для sqlite. Это не так, и если подумать, вы попадете в неприятности , особенно с предикатами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...