Основные данные: решить странную ошибку EXC_BAD_ACCESS - PullRequest
5 голосов
/ 15 июня 2011

Я столкнулся с действительно странной проблемой с Core Data.Давайте опишем это:

Определения

Допустим, у меня есть две модели, ModelA и ModelB.В модели данных ModelA имеет ссылку на ModelB как связь один-ко-многим, и, следовательно, ModelB имеет связь один-к-одному с ModelA.

Обновление

Когда приложение запускается (особенно при первом запуске) или когда пользователь спрашивает, я должен создать или обновить все экземпляры ModelB для каждого экземпляра ModelA.ModelA экземпляры предопределены.Для каждого экземпляра ModelA у меня есть около 200 экземпляров ModelB.

. Я использую такой код:

ModelB *model = [NSEntityDescription insertNewObjectForEntityForName:@"ModelB"
                                              inManagedObjectContext:context];
model.value = [NSNumber numberWithDouble:myValue];
model.modelA = modelA; // I pass modelA as a parameter to the function
[modelA addModelBObject:model];

Я не сохраняю данные сразу (так как у меня многоданные для сохранения), но я делаю это в конце процесса.

Ошибка

Иногда, и только иногда, я получаю ошибку EXC_BAD_ACCESS в этой строке:

model.value = [NSNumber numberWithDouble:myValue];

Включая зомби, я не вижу ничего, кроме этой глупой EXC_BAD_ACCESS, больше никакой информации.

Действительно странная ошибка

Я пытался установить это значение в другомпути, но ничего не изменилось.Затем я попытался retain NSNumber, но ничего не изменилось.Затем, наконец, я попытался retain однажды созданная модель, и я получил обычную EXC_BAD_ACCESS, но, соответственно, создание модели, то есть здесь:

ModelB *model = [[NSEntityDescription insertNewObjectForEntityForName:@"ModelB"
                                               inManagedObjectContext:context] retain];

Идеи?

У вас есть идеи, как решить эту проблему?Я делаю что-то неправильно?Кстати, эта проблема , по-видимому, не возникает, если я сильно замедляю работу (например, сохраняю контекст каждый раз, когда создаю новую модель), но это действительно тормозит все приложение ...

Редактировать

В некоторых редких случаях я получаю эту трассировку стека:

Serious application error.  Exception was caught during Core Data change processing.  This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification.  -[__NSCFSet addObject:]: attempt to insert nil with userInfo (null)
2011-06-15 11:36:59.864 myApp[457:607] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFSet addObject:]: attempt to insert nil'
*** Call stack at first throw:
(
0   CoreFoundation                      0x313dc64f __exceptionPreprocess + 114
1   libobjc.A.dylib                     0x34b3dc5d objc_exception_throw + 24
2   CoreFoundation                      0x313dc491 +[NSException raise:format:arguments:] + 68
3   CoreFoundation                      0x313dc4cb +[NSException raise:format:] + 34
4   CoreFoundation                      0x31351089 -[__NSCFSet addObject:] + 152
5   CoreData                            0x35136dd9 -[NSManagedObjectContext(_NSInternalChangeProcessing) _processPendingUpdates:] + 524
6   CoreData                            0x350f4b3d -[NSManagedObjectContext(_NSInternalChangeProcessing) _processRecentChanges:] + 724
7   CoreData                            0x351363a5 -[NSManagedObjectContext processPendingChanges] + 16
8   CoreData                            0x350d027f _performRunLoopAction + 126
9   CoreFoundation                      0x313b3a35 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 16
10  CoreFoundation                      0x313b5465 __CFRunLoopDoObservers + 412
11  CoreFoundation                      0x313b675b __CFRunLoopRun + 854
12  CoreFoundation                      0x31346ec3 CFRunLoopRunSpecific + 230
13  CoreFoundation                      0x31346dcb CFRunLoopRunInMode + 58
14  GraphicsServices                    0x3658841f GSEventRunModal + 114
15  GraphicsServices                    0x365884cb GSEventRun + 62
16  UIKit                               0x368ded69 -[UIApplication _run] + 404
17  UIKit                               0x368dc807 UIApplicationMain + 670
18  myApp                               0x000028cf main + 82
19  myApp                               0x00002878 start + 40
)
terminate called after throwing an instance of 'NSException'

Редактировать 2

Это трассировка стека исключения:

#0  0x313f1460 in __CFBasicHashAddValue ()
#1  0x3133fff8 in CFBasicHashAddValue ()
#2  0x31344162 in CFSetAddValue ()
#3  0x31351012 in -[__NSCFSet addObject:] ()
#4  0x3514211a in _PFFastMOCObjectWillChange ()
#5  0x3512ed46 in _PF_ManagedObject_WillChangeValueForKeyIndex ()
#6  0x35132e7e in _sharedIMPL_setvfk_core ()
#7  0x3513316a in _svfk_2 ()
#8  0x0003b750 in -[_TassoStorico setValoreValue:] (self=0x6d97bf0, _cmd=0x49064, value_=1.02600002) at _TassoStorico.m:87
#9  0x0001b62e in -[EuriborParser(hidden) readStoricoForzato] (self=0x74200d0, _cmd=0x48ff7) at EuriborParser.m:236
#10 0x31349f02 in -[NSObject(NSObject) performSelector:withObject:] ()
#11 0x000441c4 in -[MBProgressHUD launchExecution] (self=0x90a6ff0, _cmd=0x4b83f) at MBProgressHUD.m:482
#12 0x352b3388 in -[NSThread main] ()
#13 0x353255cc in __NSThread__main__ ()
#14 0x34e20310 in _pthread_start ()
#15 0x34e21bbc in thread_start ()

Ответы [ 4 ]

9 голосов
/ 15 июня 2011

CoreData не является поточно-ориентированным; похоже, это ваша проблема, попробуйте посмотреть на этот ТАК вопрос

5 голосов
/ 23 июня 2012

У меня была похожая проблема (EA_BAD_ACCESS на [managedContext save]), которая была вызвана KeyValueObserver, который не был удален, когда он должен был быть. Было довольно сложно выследить. Это означало, что у меня такое поведение даже с ARC.

1 голос
/ 10 февраля 2016

Сброс контекста вашего управляемого объекта после переноса хранилища

У меня были похожие проблемы.Я также работаю с несколькими потоками и использую функцию Core Data migratePersistentStore:toURL:options:withType:error:.

В моем случае ошибка произошла сразу после миграции в другой поток.Я подумал, что мои проблемы связаны с потоками, поэтому я начал удваивать безопасность потоков в своем коде, но на самом деле один вызов managedObjectContext.reset() перед выполнением любых последующих операций надобъекты в контексте управляемого объекта решили все проблемы.

Поведение основных данных

Как ни странно existingObjectWithID:error: всегда возвращал мне ссылку на несуществующий объект, так чтополучал доступ к несуществующим объектам и получал EXC_BAD_ACCESS.После сброса контекста функция выявила правильное поведение.

0 голосов
/ 15 июня 2011

Эти две строки избыточны и, возможно, опасны:

model.modelA = modelA; // I pass modelA as a parameter to the function
[modelA addModelBObject:model];

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

model.modelA = modelA;

... потому что это проще.

...