iPhone:地址簿有时会被删除
我在我的应用中使用 ABAddressBook
。
对 AB 的访问是从单独的线程进行的,以便释放 UI。
我知道对 AB 实例的访问必须始终来自同一个线程,因此我构建了一个包装器。
包装器是一个单例,它维护自己的后台线程。
到达包装器的所有消息都会自动重定向到后台线程,而调用线程会等待直到实现结束,并最终用相关数据(联系人列表、特定联系人等)填充 out 参数。
尽管如此,设备上的地址簿有时会变空(被删除)。
每使用该应用程序 10-20 次后。
所以,我有几个问题:
- 在专用线程中从 AB 获取 ABRecordRef 后,我是否还必须在同一线程中从 ABRecordRef 检索数据,或者可能是另一个线程?我还有一个 ABRecordRef 的包装器,因此当我从 AB 检索联系人时,我填充人员包装器对象,然后从原始线程使用它(从 ABRecordRef 读取)。
- 当我使用 AB UI API(人员选择器导航控制器、新人员视图控制器等)并将我的 ABAddressBook 实例传递给它们时,我是否必须担心 API 不会使用来自同一线程的此 AB 实例创建了它?我已经看到我可以传递 NULL 而不是 AB 实例,然后 API 将使用自己的 AB,但是当我想修改联系人时我该怎么办?在这种情况下,我必须将 ABRecordRef 实例传递给它......
- 还有什么我没有想到的吗?
先感谢您。
--
迈克尔
I use the ABAddressBook
in my app.
The access to the AB is from a separate thread in order to release the UI.
I am aware of the fact that the access to the AB instance has to be from the same thread all the time and I have built a wrapper for this reason.
The wrapper is a singleton and it maintains its own background thread.
All the messages that come to the wrapper are automatically redirected to the background thread, while the calling thread waits until the end of implementation and in the end fills the out argument with the relevant data (contacts list, a specific contact etc.).
Even though, the address book on the device gets empty (erased) sometimes.
After every 10-20-th use of the app.
So, I have few questions:
- After I get the ABRecordRef from the AB in the dedicated thread do I have to retrieve data from the ABRecordRef also in the same thread or may it be another thread? I also have a wrapper for ABRecordRef, so when I retrieve a contact from AB I fill the person wrapper object and after that I use it (read from ABRecordRef) from the original thread.
- When I use the AB UI APIs (person picker navigation controller, new person view controller etc.) and pass them my instance of ABAddressBook do I have to worry about the fact that the API won't use this AB instance from the same thread that created it? I have seen that I can pass NULL instead of the AB instance and then the API will use its own AB, but what can I do when I want to modify a contact? In this case I have to pass it the ABRecordRef instance...
- Is there something else I didn't think about?
Thank you in advance.
--
Michael
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您只能从调用 ABAddressBookCreate() 的同一线程访问通讯簿。您不能在另一个线程中使用 ABRecordRef。只有记录 ID 和复制的数据才能在线程之间安全传递。
通常,我创建一个串行调度队列并将其用作不能阻塞主线程的地址簿调用的包装器。
当您使用 UI 时,您需要在主线程上调用 ABAddressBookCreate() 并将其用于 UI 调用。
如果您需要使用 UI 修改联系人,您可以修改该联系人,保存它,然后更新后台线程或队列上的地址簿,以便它包含最新的更改。为此,有一个通知回调 ABAddressBookRegisterExternalChangeCallback。
You must only access the Address Book from the same thread that called ABAddressBookCreate(). You cannot use ABRecordRef in another thread. Only record id's and copied data are safe to pass between threads.
Typically, I create a serial dispatch queue and use it as a wrapper for Address Book calls that can't block the main thread.
When you use the UI, you need to call ABAddressBookCreate() on the main thread and use that for your UI calls.
If you need to modify a contact with the UI, you would modify the contact, save it, then update the address book on your background thread or queue, so that it contains the latest changes. There is a notification callback ABAddressBookRegisterExternalChangeCallback, for this purpose.