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

Устранение ошибки CoreData: NULL _cd_rawData, но объект не превращается в ошибку

Иногда при использовании объекта Core-Data приложение вылетает с ошибкой:

CoreData: ошибка: NULL _cd_rawData, но объект не поворачивается в неисправность

Из того, что я мог исследовать и читать из Интернета, заключается в том, что это происходит, когда контекст управляемого объекта передается между двумя потоками, а MOC не являются потокобезопасными.

Этот сбой появляется всякий раз, когда я хочу получить доступ к свойству из объекта CD.

Если у меня есть объект Person и вы хотите получить доступ к Perosn.name, приложение может потерпеть крах с этой ошибкой (как было сказано ранее, это происходит, насколько я могу видеть случайным образом, и я не могу воспроизвести его, иногда это произойдет 10 раз в строка, а затем не произойдет в течение дня или двух).

При рассмотрении этой проблемы кажется, что это происходит, когда Person получает и обновляет отношения с друзьями (это делается в фоновом потоке, сохраняется и объединяется с основным потоком MOC).

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

Ниже приведен код, в котором сохраняется контекст:

__block MyAppDelegate *blockSelf = self;
    dispatch_async(dispatch_get_main_queue(), ^{
        [blockSelf.managedObjectContext performBlock:^{
            [blockSelf.managedObjectContext save:nil];

            dispatch_async(blockSelf.core_data_queue, ^{
                [blockSelf.writerContext performBlock:^{
                    [blockSelf.writerContext save:nil];
                }];
            });
        }];
    });

Обновление 1 Иногда при выполнении saveContext я получаю следующую ошибку:

"Ошибка домена = NSCocoaErrorDomain Code = 1550" Операция не может быть выполнена. (Cocoa ошибка 1550.)

Висячая ссылка на недопустимый объект. = null

NSLocalizedDescription = Операция не может быть выполнена. (Cocoa ошибка 1550.), NSValidationErrorValue = Отслеживание "друзей" на управляемом объекте (0x201cd340)

UID: < 4C1B48C8-6309-4E8E-A590-DED497907A3A > . Идентификатор объекта: (null). с объектами {(\n '(null) "UID: < (null) > .)}}"

Я нашел этот ответ из другого вопроса: "Это было связано с тем, что объект был создан, созданный в другом контексте, обратите внимание не на другой поток только на другой контекст в том же потоке".

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

4b9b3361

Ответ 1

Хммм, некоторые вещи, которые я бы изменил в этом коде.

  • Используйте указатели ошибок, для чего они предназначены. Вероятно, вы получите решение. Перейдите в указатель NSError, проверьте возврат из вызова -save: и выплюните ошибку на консоль при сбое.

  • Управление очередью немного страшно. Вместо dispatch_async() измените это на -[NSManagedObjectContext performBlock:]. Это гарантирует, что вы находитесь в правильном потоке/очереди для контекста, к которому вы обращаетесь. С тем, как вы его написали, нет никакой гарантии, и, следовательно, ремонтопригодность низкая.

Как только вы сделаете эти два изменения, и вы все еще не сработали, обновите свой вопрос с помощью результатов объектов NSError, и мы увидим, что происходит.

Обновление 1

Даже несмотря на то, что ошибка сохраняется при сохранении, вы все равно хотите проверить это возвращаемое значение и ошибку, поскольку это может дать нам недостающую информацию.

Пожалуйста, ответьте здесь, если/когда вы воспроизводите сбой.

Обновление 2

Хорошо, это указывает на то, что вы создаете объекты в разных MOC, а затем соединяете их по уже собранным отношениям. Можете ли вы опубликовать или описать, как и когда вы создаете объекты? Какой MOC вы используете?

Можете ли вы также опубликовать обновленный код для сохранения?

Ответ 2

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

Надеюсь на эту помощь.

Ответ 3

Опираясь на ту же проблему, но решив ее установить в Fetchrequest

[fetchrequest setReturnsObjectsAsFaults:NO];