views:

237

answers:

1

My sense from the Address Book documentation and my understanding of the underlying CoreData implementation suggests that Address Book should be thread safe, and making queries from multiple threads should pose no problems. But I'm having trouble finding any explicit discussion of thread safety in the docs. This raises a few questions:

  • Is it safe to use +sharedAddressBook on multiple threads for read-only access? I believe the answer is yes.
  • For write-access on background threads, it appears that you should use +addressBook instead (and save your changes manually). Do I understand this correctly?
  • Has anyone investigated the performance impact of making multiple simultaneous queries to Address Book on multiple threads? This should be very similar to the performance of making multiple CoreData queries on multiple threads. My sense is that I would gain little by making parallel queries since I assume they will serialize when they hit SQLLite, but I'm not certain here.

I need to make dozens of queries (some complex) against AddressBook and am doing so on a background thread using NSOperation to avoid blocking the UI (which it currently does). My underlying question is whether it makes sense to set the max concurrent operations to a value larger than 1, and whether there is any danger in doing so if the application may also be writing to AddressBook at the same time on another thread.

+2  A: 

Unless an API says it is threadsafe it is not. Even if the current implementation happens to be thread safe it might not be in the future. In other words, do not use AB from multiple threads.

As an aside, what about it being CoreData based makes you think it would be thread safe? CoreData uses a thread confinement model where it is only safe to access a context on a single thread, all the objects from the context must be accessed on the same thread.

That means that sharedAddressBook will not be thread safe if it keeps an NSManagedObjectContext around to use. It would only be safe if AB creates a new context every time it needs to do something and immediately disposes of it, or if it creates a context per thread and always uses the appropriate context (probably by storing a ref to it in the threadDictionary). In either event it would not be safe to store anything as NSManagedObjects since the contexts would be constantly destroyed, which means every ABRecord would have to store an NSManagedObjectID so it could reconstitute the object in the appropriate context whenever it needed it.

Clearly all of that is possible, it may be what is done, but it is hardly the obvious implementation.

Louis Gerbarg
I'm aware of the thread/context issues with CoreData, which is why I point to the existence of the +addressBook method. If it does not provide a separate context, what possible purpose does it serve? (Granted, others have asked the same question since it's unclear from the docs how +sharedAddressBook and +addressBook differ.) Coupling lack of thread-safety, no locking mechanism, no guidance on whether mainThread is required, and extreme slowness of operation, the basic question is still out there: how to correctly write highly responsive apps that require many AB queries. Radar time...
Rob Napier