2010-01-30 4 views
3

Код:Основные данные не могут устранить ошибки, когда объект имеет атрибут «описание»?

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 

NSEntityDescription *entity = [NSEntityDescription entityForName:@"A" 
              inManagedObjectContext:moc]; 
[fetchRequest setEntity:entity]; 

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"id" ascending:NO]; 
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; 
[fetchRequest setSortDescriptors:sortDescriptors]; 
[sortDescriptors release]; 
[sortDescriptor release]; 

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"somePredicate", someObject]; 
[fetchRequest setPredicate:predicate]; 

frc = [[NSFetchedResultsController alloc] 
     initWithFetchRequest:fetchRequest 
     managedObjectContext:moc 
     sectionNameKeyPath:@"recency" 
     cacheName:@"frc"]; 
[fetchRequest release]; 

frc.delegate = self; 

NSError *error; 
BOOL success = [frc performFetch:&error]; 
if (!success) { 
    NSLog(@"error: %@", error); 
} 

for (A *a in [frc fetchedObjects]) {   
    [someMutableArray addObject:a.b]; 
    [someMutableArray addObject:a]; 
} 

модель данных:

А и В являются сущностями. А имеет обязательное к одному отношению к B. B имеет обратное дополнительно ко многим отношения к А.

Выше на английском языке:

Инициализировать NSFetchedResultsController, чтобы захватить некоторые данные для питания TableView. После первоначальной выборки отложите данные для некоторой обработки.

Теперь, позже, я пытаюсь сделать это:

id object = [someMutableArray objectAtIndex:someIndex]; 
NSLog(@"%@", object); 

if ([object isMemberOfClass:[B class]]) { 
    someVar = object.propertyFromB; // problem 
} else if ([object isMemberOfClass:[A class]]) { 
    someVar = object.propertyFromA; 
} 

Вопрос/проблема: линия обозначена "проблемных" аварий. (EDIT: смотрите ниже разрешение, но все же хотел объяснения.)

Вызов NSLog выше, дает:

2010-01-30 14:47:14.433 app[22618:20b] <B: 0xf7f750> (entity: B; id: 0xf7ba70 <x-coredata://B01FEC86-14D6-4973-BFDB-EDE4AFD24FDC/B/p4> ; data: <fault>) 
2010-01-30 14:47:14.438 app[22618:20b] <A: 0xf7e360> (entity: A; id: 0xf35820 <x-coredata://B01FEC86-14D6-4973-BFDB-EDE4AFD24FDC/A/p6> ; data: { 
    prop1 = value1; 
    prop2 = value2; 
    ... etc ... 
}) 

Ie по проблемному линии, если объект был типа А, это было неисправен и доступен в памяти, но если это B, это ошибка.

Мое понимание заключается в том, что строка «проблема» должна запускать ошибку и извлекать данные из хранилища, но этого не происходит. Я хотел бы понять/отладить почему. Я попытался вставить вызовы willAccessKey/didAccessKey вокруг этого. Я также попытался установить setRelationshipKeyPathsForPrefetching: «b» в запросе выборки. Ничего не сработало.

Моя гипотеза заключается в том, что, поскольку я несколько злоупотребляю результатами NSFetchedRequestController, механизм сбоев путается по пути и не приносит ошибку, когда это предполагается. Поэтому я предполагаю, что метод bruteforce должен был бы создать новый запрос ручной выборки для извлечения связанного объекта B в нужное время. Но есть ли лучший способ?

EDIT:

Проблема заключалась в том, что объект B имел свойство «описание», который я определил, но сталкивается со встроенным в имени NSObject в. Xcode всегда давал мне предупреждения, но я их игнорировал, потому что я думал, что внутреннее свойство/метод описания «description» используется только для сброса строк на консоль и т. П., А не для внутренней обработки.

Проблема исчезла после того, как я сделал новую версию своей модели, переименовав «описание» в нечто другое. Все сбои начали работать, как ожидалось.

Я не понимаю, однако, что происходит. Являются ли основные данные использующими метод «описания» объектов для некоторой внутренней самоанализа?

ответ

6

От Core Data Programming Guide

Вы обескуражены переопределение Описание, если этот метод срабатывает неисправность во время операции отладки, результаты могут быть непредсказуемыми, и initWithEntity: insertIntoManagedObjectContext :. Обычно вы не должны переопределять методы кодирования значения ключа, такие как valueForKey: и setValue: forKeyPath :.

-description - метод в NSObject, который возвращает строковое представление вашего объекта.В строке NSLog(@"%@", object), -description используется для получения строки, которую вы видите в консоли. Ключевое значение кодирования закончится тем, что метод получит свойство для атрибута описания. Это вызывает много путаницы с Core Data.

Руководство по программированию щедро, когда оно говорит «обескураженно». Они действительно означают «Да, это сломает ваши вещи».

Эта ссылка также содержит хороший список других методов, которые могут сломать ваши вещи, если вы их переопределите.

+0

Это все имеет смысл, и я вообще стараюсь воздерживаться от переопределения таких «хорошо известных» методов. Мой плохой для того, чтобы не понять, насколько чувствительным является «описание». – Jaanus

0

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

+0

Я действительно получил предупреждение. Я думал, что буду игнорировать его в то время, поскольку у меня не было никаких проблем в начале, когда я начал создавать объекты. Оказывается, это была плохая идея :) – Jaanus

+1

Да, игнорирование предупреждений - плохая идея. Каждый разработчик должен стремиться к предупреждению бесплатной сборки! Возможно, даже установите «предупреждения как ошибки». – Hunter

+0

Есть ли лучшая практика для моделирования объектов, которые имеют атрибут «описание»? Люди склонны называть это «desc» или что-то еще? – Hugh

0

Для специальных описаний вы можете переопределить -(NSString *)debugDescription из протокола NSObject. Из документа Apple:

NSObject реализует этот метод, обратившись к методу описания. Таким образом, по умолчанию описание отладки объекта такое же, как и его описание . Однако вы можете переопределить debugDescription, если хотите, отделить их.