EXC_BAD_ACCESS в NSManagedObjectContext метод сохранения внутри NSOperation и ARC, почему? - PullRequest
10 голосов
/ 23 февраля 2012

Я обнаружил некоторые проблемы при сохранении NSManagedObjectContext внутри NSOperation с включенным ARC. Без ARC все было хорошо раньше. Это всегда дает EXC_BAD_ACCESS во время сохранения. Код выглядит так:

//on the main thread
-(void)someFunc
{
    array = ... //fetching an array of entities from a core data
    for(SomeEntity * obj in array)
    {
         NSSomeOperation * op = [[NSSomeOperation alloc] initWithValue:[obj someField]];
         //start an operation
    }
}

//NSSomeOperation implementation
//...
- (void)main {
    //some code
    NSError * error = nil;
    [mainContext lock];
    if (![mainContext save:&error]) {    //<--- HERE EXC_BAD_ACCESS
       //process error
    }      
    [mainContext unlock];
    //some code
}
//...

Использование [mainContext setRetainsRegisteredObjects: YES] и objectWithID не решает эту проблему.

EXC_BAD_ACCESS (код = 1)
EXC_BAD_ACCESS (код = 13)

-[__NSCFType contextDidSave:]: unrecognized selector sent to instance 0x7fc5c505d940

An observer of NSManagedObjectContextDidSaveNotification illegally threw an exception.

Objects saved = {
    inserted = "{(\n)}";
    updated = "{(\n    <SomeEntity: 0x7fc5c55b6220> (entity: SomeEntity; id: 0x7fc5c5052b20 ... )}"; } 
and exception = -[__NSCFType contextDidSave:]: unrecognized selector sent to instance 0x7fc5c505d940 with userInfo = (null)

Я использую отдельный контекст управляемого объекта и извлекаю свои управляемые объекты внутри этой NSOperation.

Может быть, это связано с ошибками Core Data или ARC? Может быть, ARC очищает некоторые объекты, которые нужно сохранить? Потому что без ARC все было хорошо, все работало. Когда я включил ARC - EXC_BAD_ACCESS.

Кто-нибудь знает, почему это происходит?

1 Ответ

26 голосов
/ 25 февраля 2012

Может быть, ARC освобождает некоторый объект, который получает NSManagedObjectContextDidSaveNotification , и это вызывает исключение? У меня было нечто подобное, и я исправил это, убедившись, что removeObserver: , прежде чем объект будет освобожден.

Обратите внимание, что исключение CoreData фактически скрывает исключение центра уведомлений, поэтому вы его не увидите.

...