2011-11-25 26 views
4

我的应用程序有一个NSOperation,打开iPhone地址簿,循环通过用户的联系人,并将姓名和电话号码复制到核心数据实体。大多数情况下,这个工作没有问题,但很少看起来地址簿被破坏,所有联系人都丢失了。我没有对地址簿进行任何写入,所以不确定这是怎么发生的。它不会抛出堆栈跟踪或崩溃应用程序。我只是在我再次运行我的应用程序后才注意到它。我看到在日志中下面...迭代通过iPhone通讯录导致地址簿的SQL数据库损坏

CPSqliteStatementSendResults:文件被加密或不是数据库 checkResultWithStatement:文件被加密或不适合SELECT UID,标识符(SELECT值FROM ABMultiValueLabel WHERE ROWID =标签数据库),值FROM ABMultiValue WHERE record_id =? AND属性+ 0 =?;

...并且地址簿是空的。

是否有可能通过读取地址本而不是正确地关闭地址簿?

+0

地址簿是否也停止为'Contacts'应用程序工作,或者这个问题仅与您的应用程序隔离? – tidwall

+0

发生这种情况后,通讯录中的地址簿为空。联系人应用运行正常,只有零个条目。我并没有编辑我的代码中的任何地址簿,这让我感到莫名其妙。 –

+0

它在模拟器和设备上都发生过吗? – shannoga

回答

3

这件事确实发生在我身上。

您正在从两个不同的线程访问相同的AB实例,并且地址簿不是线程安全的。

您需要使用ABAddressBookCreate()来获取在每个单独线程上使用的实例。

从文档:Important: Instances of ABAddressBookRef cannot be used by multiple threads. Each thread must make its own instance.

你可以阅读更多关于它here

我已经确认,如果您确实从多个线程读取数据库将会损坏,并且用户将失去所有联系人。

+0

我们使用Erica Sadun的ABContactsHelper包装类来处理所有的联系人提取。看起来它为所有访问地址簿的函数分离了ABAddressBookCreate()。我会给应用程序添加一些调试,看看我是否可以检测到我们跨线程使用同一个地址簿实例的任何地方。 –