Итерация адресной книги iPhone, вызывающая повреждение адресной книги sql db

В моем приложении есть NSOperation, который открывает адресную книгу iphone, перебирает контакты пользователей и копирует имя и номер телефона в объекты Core Data. В большинстве случаев это работает без проблем, но редко кажется, что адресная книга повреждена и все контакты потеряны. Я не делаю никаких записей в адресную книгу, поэтому не знаю, как это могло произойти. Он не создает трассировку стека и не приводит к сбою приложения. Я замечаю это только после того, как снова запускаю свое приложение. В логе вижу следующее...

CPSqliteStatementSendResults: файл зашифрован или не является базой данных checkResultWithStatement: файл зашифрован или не является базой данных для SELECT UID, идентификатора (SELECT value FROM ABMultiValueLabel WHERE ROWID = label), значение FROM ABMultiValue WHERE record_id = ? И свойство+0 = ?;

...и адресная книга пуста.

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


person Kirby Todd    schedule 25.11.2011    source источник
comment
Перестает ли работать адресная книга и для Contacts приложения, или эта проблема касается только вашего приложения?   -  person tidwall    schedule 30.11.2011
comment
После этого адресная книга в приложении «Контакты» пуста. Приложение «Контакты» работает нормально, просто в нем нет записей. Я нигде в своем коде не редактирую адресную книгу, вот что меня сбило с толку.   -  person Kirby Todd    schedule 01.12.2011
comment
Это произошло как на симуляторе, так и на устройстве?   -  person shannoga    schedule 01.12.2011
comment
Видел только на устройстве. До сих пор никогда на симуляторе или устройстве в режиме отладки с Xcode. Это довольно трудно поймать, потому что оно не падает, и мы не знаем, что это произошло, до следующего запуска приложения, когда адресная книга будет очищена.   -  person Kirby Todd    schedule 01.12.2011
comment
Используете ли вы создание собственного NSOperationQueue или используете [NSOperationQueue mainQueue]?   -  person tidwall    schedule 01.12.2011
comment
Мы используем нашу собственную NSOperationQueue.   -  person Kirby Todd    schedule 02.12.2011


Ответы (1)


Именно это случилось со мной раньше.

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

Вам нужно использовать ABAddressBookCreate(), чтобы получить экземпляр для использования в каждом отдельном потоке.

Из документации: Important: Instances of ABAddressBookRef cannot be used by multiple threads. Each thread must make its own instance.

Подробнее об этом можно прочитать здесь.

Я подтвердил, что если вы читаете из нескольких потоков, база данных будет повреждена, и пользователь потеряет все свои контакты.

person Zebs    schedule 02.12.2011
comment
Мы используем класс-оболочку ABContactsHelper Эрики Садун для обработки всех выборок контактов. Кажется, что он разделяет ABAddressBookCreate() для всех своих функций, которые обращаются к адресной книге. Я добавлю немного отладки в приложение и посмотрю, смогу ли я обнаружить где-нибудь, где мы используем один и тот же экземпляр адресной книги в разных потоках. - person Kirby Todd; 02.12.2011