With the impending release of the iPad 2, understanding how to program multithreaded applications will quickly become paramount as applications continue to push the envelope to make immersive experiences with high-performance computation. Now, without actually having a multicore iPad in my hands, I can’t say exactly how the system will behave, but there are a few best practices we should all be aware of when writing iOS code:
- Using Core Data? You can’t share access to an
NSManagedObjectContext
across multiple threads, dispatch queues, orNSOperation
queues, so for each one you’ll need to create a new instance. Similarly, don’t pass anNSManagedObject
or subclass thereof between threads. Give each of your objects a unique ID—CFUUID
works well for this—and pass the ID around, pulling a new object out of yourNSManagedObjectContext
for each thread. It’s a pain, but that’s how to (safely) get around threading and Core Data. - Always call UIKit updates from the main thread. Whatever you’re doing to your user interface, be it updating a label, loading an image into an image view, anything that’ll be rendered to screen—and some things that won’t—should be run on the main thread. There are two main ways to do this:
- Use Grand Central Dispatch. Using
dispatch_get_main_queue()
, you can get a reference to the main queue and submit blocks to it for updating your UI. This is typically a clean, easy way to refactor existing code for thread-aware programming. - Use
-performSelectorOnMainThread:withObject:waitUntilDone:
and friends. This has the drawback of only working for methods that take one or zero Objective-C objects as arguments, but can be a quick and easy way to use fire-and-forget methods like-reloadData
onUITableView
.
- Use Grand Central Dispatch. Using
- Think about how you declare your properties. How many people have been using atomic properties? Before now, not many. In fact, before now, it was typically useless, as the chances of something interrupting your accessor methods was pretty low. Now, though, if you’re planning on accessing an object from multiple threads, you really need to control access to your properties.
- Use locks. Locks, long the scourge of the multithreaded-code author, are simply essential for some parts of multithreaded programming. Whether you’re using
NSLock
or a lower-level lock, or even something like Grand Central Dispatch’s counting semaphore type,dispatch_semaphore_t
, protect critical regions of your code from multiple accessors with (carefully-thought-out) locked access.
This list is by no means exhaustive, and Apple can do a lot to make this irrelevant (such as make UIKit threadsafe, which would be a killer iOS 5.0 feature), but with the iPad 2’s arrival, developers can no longer assume safety from threading problems. Be sure also to read Apple’s Threading Programming Guide to get anything I’ve left out.
It also makes a great excuse to buy an iPad 2. I mean, you need to test this, right?