Подтвердить что ты не робот

NSManagedObjectContext: точка останова исключений останавливается при сохранении: метод, но нет ошибок журнала/сбоя/ошибки

Я использую CoreData в многопоточном iOS-приложении, и все, кажется, работает нормально - если я не включу контрольную точку исключения в XCode. Всякий раз, когда я выполняю некоторую работу с CoreData, точка останова останавливается на save: -методе на NSManagedObjectContext, но NSError имеет значение nil впоследствии. У меня также нет ничего в журнале (кроме: Catchpoint 2 (exception thrown).), приложение не разбивается... Так что довольно сложно сказать, что происходит не так.

Единственный ключ, который у меня есть, это то, что у меня есть один объект в updatedObjects: в моем NSManagedObjectContext, но в нем нет ничего плохого.

Мой вопрос очень похож на qaru.site/info/119063/..., но единственный ответ мне не помогает; Я почти уверен, что у меня все там покрыто.

Что здесь может быть неправильным? Или есть другие возможности для получения информации об ошибке?

Большое спасибо!

EDIT: показать код довольно сложно. Я загружаю объекты с помощью objectID, редактирую и сохраняю их в контексте, назначенном текущему потоку. Я уже проверил - контекст всегда корректен для текущего потока; каждый поток имеет свой собственный контекст, который не должен быть проблемой. Было бы даже полезно, если бы кто-то мог сказать мне, как получить больше информации от этой ошибки/исключения - или если мне все-таки нужно это делать. Мне кажется, что исключение попадает в "save" -метод, так что, возможно, это "нормальное" поведение?

4b9b3361

Ответ 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) в мою установку стека.