Я написал минимальный пример кода проблемы, с которой я столкнулся. Я реализовал фоновую работу двумя способами: вручную порождая потоки и позволяя NSOperation
обрабатывать потоки. В обоих случаях я создаю NSManagedObjectContexts
для каждого потока / операции.
Когда я сам создаю темы с performSelectorInBackground:withObject:
, все работает нормально. Когда я переключаюсь на передачу своих объектов на NSOperationQueue
, я вижу следующие ошибки при попытке сохранить операции NSManagedObjectContext
.
-EXC_BAD_ACCESS
- Серьезная ошибка приложения. Исключительная ситуация при обработке изменения базовых данных: *** - [NSCFSet addObject:]: попытка вставить ноль
с userInfo (ноль)
- _referenceData64 определено только для абстрактного класса. Определить - [NSTevenObjectID_default _referenceData64]!
Я считаю, что ошибка, особенно с учетом последней ошибки, связана с использованием временного objectID для передачи объектов между потоками / контекстами. Возможно, что еще хуже, я как-то передаю NSManagedObjects
между потоками.
В любом случае, я не могу найти код, который бы подсказывал, что я делаю это.
Мой пример минимального кода можно найти здесь .
Большая часть работы выполняется в AppDelegate
в awakeFromNib
. Установите EXECUTE_WITH_NSOPERATION
в 0 для запуска с performSelectorInBackground:withObject:
. Оставьте EXECUTE_WITH_NSOPERATION
на 1 для выполнения с NSOperationQueue
, который создает группу MCBoardParse
объектов.
Я вижу это только под 10.6.
Оригинал
У меня есть приложение Какао, построенное на платформах 10.5. В NSOperation
В цикле я быстро создаю сотни NSManagedObjects
. Часто создание этих NSManagedObejcts
завершается с ошибкой EXC_BAD_ACCESS. Это происходит как при управлении подсчетом ссылок, так и при сборке мусора.
for (offsetCount; offsetCount < [parsedData count]; offsetCount++) {
NSManagedObject *child = [NSEntityDescription insertNewObjectForEntityForName:@"Thread" inManagedObjectContext:[self moc]];
Thumbnail *thumb = [Thumbnail insertInManagedObjectContext:[self moc]];
Image *image = [Image insertInManagedObjectContext:[self moc]];
...
}
Эскиз и изображение являются подклассами NSManagedObject
, созданными с помощью mogenerator. insertInManagedObjectContext:
выглядит как
NSParameterAssert(moc_);
return [NSEntityDescription insertNewObjectForEntityForName:@"Thumbnail" inManagedObjectContext:moc_];
NSParameterAssert(moc_);
return [NSEntityDescription insertNewObjectForEntityForName:@"Image" inManagedObjectContext:moc_];
The NSManagedObjectContext returned by [self moc] is created for the NSOperation with
NSPersistentStoreCoordinator *coord = [(MyApp_AppDelegate *)[[NSApplication sharedApplication] delegate] persistentStoreCoordinator];
self.moc = [[NSManagedObjectContext alloc] init];
[self.moc setPersistentStoreCoordinator:coord];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(contextDidSave:)
name:NSManagedObjectContextDidSaveNotification
object:self.moc];
[self.moc setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
[self.moc setUndoManager:nil];
[self.moc setRetainsRegisteredObjects:YES];
moc определяется как (nonatomic, retain)
и синтезируется. Насколько я могу судить, постоянное хранилище и мой appDelegate
не имеют никаких оснований и не собирают мусор.
Трассировка стека выглядит как
Thread 2 Crashed: Dispatch queue: com.apple.root.default-priority
0 libauto.dylib 0x00007fff82d63600 auto_zone_root_write_barrier + 688
1 libobjc.A.dylib 0x00007fff826f963b objc_assign_strongCast_gc + 59
2 com.apple.CoreFoundation 0x00007fff88677068 __CFBasicHashAddValue + 504
3 com.apple.CoreFoundation 0x00007fff88676d2f CFBasicHashAddValue + 191
4 com.apple.CoreData 0x00007fff82bdee5e -[NSManagedObjectContext(_NSInternalAdditions) _insertObjectWithGlobalID:globalID:] + 190
5 com.apple.CoreData 0x00007fff82bded24 -[NSManagedObjectContext insertObject:] + 148
6 com.apple.CoreData 0x00007fff82bbd75c -[NSManagedObject initWithEntity:insertIntoManagedObjectContext:] + 716
7 com.apple.CoreData 0x00007fff82bdf075 +[NSEntityDescription insertNewObjectForEntityForName:inManagedObjectContext:] + 101
8 com.yourcompany.MyApp 0x000000010002c7a7 +[_Thumbnail insertInManagedObjectContext:] + 256 (_Thumbnail.m:14)
9 com.yourcompany.MyApp 0x000000010002672d -[ThreadParse main] + 10345 (ThreadParse.m:174)
10 com.apple.Foundation 0x00007fff85ee807e -[__NSOperationInternal start] + 698
11 com.apple.Foundation 0x00007fff85ee7d23 ____startOperations_block_invoke_2 + 99
12 libSystem.B.dylib 0x00007fff812bece8 _dispatch_call_block_and_release + 15
13 libSystem.B.dylib 0x00007fff8129d279 _dispatch_worker_thread2 + 231
14 libSystem.B.dylib 0x00007fff8129cbb8 _pthread_wqthread + 353
15 libSystem.B.dylib 0x00007fff8129ca55 start_wqthread + 13
Мое приложение аварийно завершает работу в других местах с EXC_BAD_ACCESS, но это код, с которым это происходит чаще всего. Все трассировки стека выглядят одинаково и имеют отношение к CFHash
.