6

ABAddressBook在我的应用程序中使用。
对 AB 的访问来自一个单独的线程,以释放 UI。
我知道对 AB 实例的访问必须始终来自同一个线程,因此我构建了一个包装器。
包装器是一个单例,它维护自己的后台线程。
到达包装器的所有消息都会自动重定向到后台线程,而调用线程一直等到执行结束,最后用相关数据(联系人列表、特定联系人等)填充 out 参数。

即使,设备上的通讯录有时也会变空(删除)。
每 10-20 次使用该应用程序后。

所以,我有几个问题:

  • 在专用线程中从 AB 获取 ABRecordRef 后,我是否还必须在同一个线程中从 ABRecordRef 检索数据,或者它可能是另一个线程?我还有一个 ABRecordRef 的包装器,所以当我从 AB 检索联系人时,我填充了 person 包装器对象,然后我从原始线程中使用它(从 ABRecordRef 读取)。
  • 当我使用 AB UI API(人物选择器导航控制器、新人物视图控制器等)并将我的 ABAddressBook 实例传递给它们时,我是否必须担心 API 不会使用来自同一线程的这个 AB 实例创造了它?我已经看到我可以传递 NULL 而不是 AB 实例,然后 API 将使用自己的 AB,但是当我想修改联系人时该怎么办?在这种情况下,我必须将 ABRecordRef 实例传递给它......
  • 还有什么我没有想到的吗?

先感谢您。

——
迈克尔

4

1 回答 1

4

您只能从调用 ABAddressBookCreate() 的同一线程访问通讯簿。您不能在另一个线程中使用 ABRecordRef。只有记录 ID 和复制的数据可以安全地在线程之间传递。

通常,我创建一个串行调度队列并将其用作不能阻塞主线程的通讯簿调用的包装器。

当您使用 UI 时,您需要在主线程上调用 ABAddressBookCreate() 并将其用于您的 UI 调用。

如果您需要使用 UI 修改联系人,您可以修改联系人,保存它,然后更新后台线程或队列中的通讯录,使其包含最新的更改。为此,有一个通知回调ABAddressBookRegisterExternalChangeCallback。

于 2012-01-12T21:16:21.563 回答