«Канал базы данных недоступен» - PullRequest
10 голосов
/ 26 сентября 2011

У меня есть приложение, которое подключается к Интернету и сохраняет данные в базе данных SQL. Я тестировал с iOS4, все работает как надо. Однако при обновлении до новой версии я получаю исключение NSInternalInconsistencyException по следующей причине:

'_ receiveOpenChannel - NSSQLCore 0x951a640: канал базы данных недоступен'

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

Может ли кто-нибудь помочь мне найти и правильно диагностировать мою проблему?

Ответы [ 2 ]

5 голосов
/ 04 ноября 2011

Я нашел что-то для этого:

Я получил ошибку (среди прочих, которая, казалось бы, появлялась случайным образом), когда я обращался к отношениям управляемого объекта в потоке, отличном от того, в котором был создан управляемый контекст. Произошли некоторые изменения в отношении одновременный доступ к управляемым объектам в iOS5 (см. здесь http://developer.apple.com/library/ios/#releasenotes/DataManagement/RN-CoreData/_index.html#//apple_ref/doc/uid/TP40010637) - и хотя в документе указано, что поведение по умолчанию должно быть как до iOS5, это явно не соответствует действительности, мой код работал без проблем в iOS4.2 .

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

1 голос
/ 05 сентября 2013

Этот тип параллелизма по умолчанию для NSManagedObjectContext равен NSConfinementConcurrencyType, что означает, что он может использоваться только одним потоком. Из документации:

Вы обещаете, что контекст не будет использоваться никаким потоком, кроме тот, на котором вы его создали.

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

[[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]

Чтобы использовать контекст управляемого объекта из другого потока, используйте performBlock: (асинхронный) или performBlockAndWait: (синхронный), например,

__block NSArray *results;
[[self managedObjectContext] performBlockAndWait:^{
    results = [[self managedObjectContext] executeFetchRequest:request error:&error];
}];
// do something with results

В документации сказано, что вам не нужно использовать блочный API из потока, который создал контекст управляемого объекта.

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

См. Примечания к выпуску iOS 5 для получения дополнительной информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...