Странный сбой при сохранении managedObjectContext - PullRequest
0 голосов
/ 25 августа 2010

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

 TJModel *model = [TJModel sharedTJModel];
 NSFetchRequest *request = [[[NSFetchRequest alloc] init]autorelease];
 [request setReturnsObjectsAsFaults:NO];
 NSEntityDescription *entity = [NSEntityDescription entityForName:@"TJVideoList"inManagedObjectContext:[model managedObjectContext]];
 [request setEntity:entity];

 NSError *error = nil;
 NSMutableArray *mutableFetchResults = [[[model managedObjectContext] executeFetchRequest:request error:&error] mutableCopy];

if (error != nil)
  NSLog(@"error %@",[error localizedDescription]);


 TJVideoList *videoList = nil;

 if ([mutableFetchResults count] == 0) {

  videoList = (VideoList *)[NSEntityDescription insertNewObjectForEntityForName:@"TJVideoList" 
                 inManagedObjectContext:[model managedObjectContext]];
 }
 else 
 {
  videoList = [mutableFetchResults objectAtIndex:0];
 }


 [videoList addVideoListObject:recordedVideo];
 error = nil;

 if (![[model managedObjectContext] save:&error]) {

И сбой ..... Это то, что сказано в терминале:

-[NSConcreteValue UTF8String]: unrecognized selector sent to instance 0x1d33f0

Я подумал, что это может быть вызов освобожденных объектов, поэтомуЯ сохранил их так:

[managedObjectContext setRetainsRegisteredObjects:YES];

Без удачи.

Ответы [ 2 ]

1 голос
/ 26 августа 2010

Ваш сбой не является результатом этого кода.

Сбои в сохранениях обычно происходят из-за ошибки с атрибутами управляемого объекта. В этом случае вы где-то присвоили неверное значение строковому атрибуту. Когда контекст переходит для преобразования строкового атрибута в строку UTF8 для сохранения, объект, который находится там вместо NSString, не понимает сообщение и приводит к сбоям.

Хотя этот код должен работать нормально, у вас есть несколько рискованных практик:

NSFetchRequest *request = [[[NSFetchRequest alloc] init]autorelease];

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

Вы должны использовать autorelease только тогда, когда текущая область видимости сделана с объектом, но объект отправляется за пределы области видимости (обычно в методе return.)

NSMutableArray *mutableFetchResults = [[[model managedObjectContext] executeFetchRequest:request error:&error] mutableCopy];

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

videoList = [mutableFetchResults objectAtIndex:0]

Поскольку у вас нет дескриптора сортировки для выборки, массив mutableFetchResults будет в случайном порядке. Если вам возвращено более одного объекта, что почти всегда так, вы будете получать случайный объект TJVideoList с нулевым элементом при каждом запуске кода.

1 голос
/ 25 августа 2010

Похоже, вы назначили экземпляр NSValue (NSNumber, скорее всего, так как это наиболее часто используемый подкласс), где ожидалась строка NSString. -RetainsRegisteredObjects: вряд ли понадобится (в любом случае это не решит проблему, связанную с памятью).

Возможно, это проблема перевыпуска. Попробуйте запустить с включенным обнаружением зомби (см. Меню «Выполнить»).

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