NSManagedObjectContext: точка останова исключений останавливается при сохранении: метод, но нет ошибок журнала/сбоя/ошибки
Я использую CoreData в многопоточном iOS-приложении, и все, кажется, работает нормально - если я не включу контрольную точку исключения в XCode. Всякий раз, когда я выполняю некоторую работу с CoreData, точка останова останавливается на save:
-методе на NSManagedObjectContext
, но NSError имеет значение nil впоследствии. У меня также нет ничего в журнале (кроме: Catchpoint 2 (exception thrown).
), приложение не разбивается... Так что довольно сложно сказать, что происходит не так.
Единственный ключ, который у меня есть, это то, что у меня есть один объект в updatedObjects:
в моем NSManagedObjectContext
, но в нем нет ничего плохого.
Мой вопрос очень похож на qaru.site/info/119063/..., но единственный ответ мне не помогает; Я почти уверен, что у меня все там покрыто.
Что здесь может быть неправильным? Или есть другие возможности для получения информации об ошибке?
Большое спасибо!
EDIT: показать код довольно сложно. Я загружаю объекты с помощью objectID, редактирую и сохраняю их в контексте, назначенном текущему потоку. Я уже проверил - контекст всегда корректен для текущего потока; каждый поток имеет свой собственный контекст, который не должен быть проблемой. Было бы даже полезно, если бы кто-то мог сказать мне, как получить больше информации от этой ошибки/исключения - или если мне все-таки нужно это делать. Мне кажется, что исключение попадает в "save" -метод, так что, возможно, это "нормальное" поведение?
Ответы
Ответ 1
Это нормальное поведение. CoreData использует броски исключений и обработку внутри для некоторой части своего потока программы. Об этом я говорил с людьми CoreData. Это может показаться странным, но это дизайнерское решение, которое они сделали давно.
Когда вы попадаете в исключение, убедитесь, что ни один из ваших кодов в обратном канале между вашим вызовом -[NSManagedObjectContext save:]
и вызываемым исключением. Вызов -save:
, скорее всего, перезвонит вам в ваш код, например. если вы наблюдаете NSManagedObjectContextObjectsDidChangeNotification
, и если вы делаете плохие вещи, когда работаете с этим уведомлением, очевидно, что вы ошибаетесь.
Если вы выходите из метода -save:
, а возвращаемое значение YES
, все будет хорошо.
Обратите внимание, что вы должны проверить возвращаемое значение, не используйте error != nil
для проверки на наличие ошибки. Правильная проверка:
NSError *error = nil;
BOOL success = [moc save:&error];
if (!success) {
// do error handling here.
}
Ответ 2
Вы можете избежать этих бесполезных перерывов; как указывали другие, это нормальное поведение CoreData (но очень раздражает!)
- Удалить контрольную точку "Все Objective-C Исключения"
- Добавить символическую точку останова на
objc_exception_throw
- Установите условие на точку останова на
(BOOL)(! (BOOL)[[(NSException *)$eax className] hasPrefix:@"_NSCoreData"])
- Я также хотел бы добавить команду action, debugger, "po $eax", которая обычно печатает детали исключения
$eax - правильный регистр для симулятора, $r0 работает на устройствах. Вы можете создать две отдельные точки останова и включить/отключить их по мере необходимости.
См. Игнорировать некоторые исключения при использовании точки останова Xcode All Exceptions для исходного ответа
Ответ 3
У меня была аналогичная проблема. В конце концов, я понял проблему:
Я добавил наблюдателя в NSManagedObjectContextDidSaveNotification, который был освобожден без удаления из центра уведомлений. Когда его память была привязана к другому объекту, центр уведомлений попытался вызвать этот объект и вызвал исключение, потому что он не смог найти правильный селектор. По какой-то причине это исключение было "невидимым", но заставило CoreData создать собственное исключение.
Хорошо установленный вызов removeObserver: исправил проблему.
Надеюсь, это поможет кому-то другому, кто сталкивается с этой ситуацией.
Ответ 4
У меня была аналогичная проблема в моем коде. Наконец, я обнаружил, что проблема связана с изменением моей модели, и используемая мной EncryptedCoreData
NSPersistentStoreCoordinator
не была настроена для автоматической миграции, как я и ожидал в MagicalRecord в прошлом.
Единственным симптомом была эта точка останова без каких-либо других сообщений. Он был решен (временно), удалив и переустановив приложение и навсегда, добавив версии модели и соответствующий ключ (NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true
) в мою установку стека.