2010-06-09 3 views
0

У меня есть NSOperation, который извлекает некоторые объекты из постоянного хранилища данных и суммирует несколько итогов. Иногда объект удаляется во время текущей операции, поэтому возникает исключение сбоя основной информации. Я пытаюсь/улавливаю исключение при суммировании, чтобы игнорировать его, потому что просто хочу пропустить объекты, которые не могут быть сбой.Исключение сбоя разбивает регистр, вызывающий сбои в [NSInvocation invoke]

Однако, когда происходит одно из этих исключений ошибок (и я проглатываю его), происходит сбой после вызова возвращается в [NSInvocation invoke]. Это плохой доступ к памяти, когда разыменования значения в r10, которое в соответствии с GDB на успешных точки бегите к одному из них:

(gdb) x 0x38388348 
0x38388348 <OBJC_IVAR_$_NSInvocation._retdata>:  0x00000008 

Если исключение ошибки произошло значение 0x02 в регистре, который вызывает сбой.

Быстрый поиск в Google говорит мне, что r10 должен быть сохранен вызываемым пользователем, то есть он не восстанавливается каким-либо кодом, изменяющим его при возникновении этого исключения.

Может ли кто-нибудь объяснить это? Я не эксперт, когда речь заходит об этих типах деталей низкого уровня.

ответ

0

Думаю, вы задаете неправильный вопрос. Приложение Cocoa никогда не должно генерировать исключение при нормальной работе. Вам нужно решить причину этого исключения, прежде чем делать что-либо еще.

Вы не должны получать доступ к одному контексту управляемого объекта из нескольких потоков, или если вам нужно его заблокировать очень осторожно. Многопоточный доступ к одному контексту крайне опасен и может привести к тому поведению, которое вы наблюдаете. Из "Multi-Threading with Core Data" раздела Руководства по программированию Ядра данных:

Если вы хотите работать с управляемым объекта между различными потоками, вы должны заблокировать его контекст (см NSLocking). Если вы пытаетесь передать реальные объекты, доля контексты между нитями, и так , вы должны быть очень осторожны о блокировке (и, как следствие вы, вероятно, свести на нет все преимущества вы можете в противном случае вывести из мульти- нарезания резьбы). Работа с управляемого объекта через различные нитей поэтому сильно обескуражен, как описано в «Общем руководстве по .»

Рекомендуется использовать отдельный контекст управляемый объект для фонового потока (с тем же постоянное хранилище и модель управляемых объектов) и делать все необходимые для вашей операции суммирования.

+0

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

+0

@Mike Weller - Если вы правильно поняли, вы создали отдельный контекст управляемого объекта для своей фоновой операции, но вы получаете исключения, когда пытаетесь сбой в некоторых управляемых объектах из постоянного хранилища, потому что они были удалены в отдельном контексте, который записал эти изменения на диск. В этом случае вам необходимо убедиться, что ваш фоновый контекст согласовывает изменения, как описано здесь: http://developer.apple.com/iphone/library/documentation/cocoa/conceptual/CoreData/Articles/cdChangeManagement.html# // apple_ref/doc/uid/TP30001201-CJBDBHCB –

+0

Я знаком с разрешением конфликтов. Проблема в том, что когда операция извлекает объекты, они, очевидно, все существуют.Есть много объектов и их итерации, и вычисление информации занимает много времени. Возможность обнаружить удаление из другого контекста и как-то удалить ссылки на удаленные объекты просто невозможно в операции. Мое текущее обходное решение - это просто проверить результат [context existingObjectWithID:] перед доступом к членам объекта. Если элемент был удален, он возвращает нуль. Теоретически это «раса-у», но на практике это должно быть хорошо. –