views:

222

answers:

2

Background

I'm a developer who's in the throes of building an application for the Mac. I'm about to get my hands on Snow Leopard. Until now I've been building on Leopard. I've only been doing Cocoa development for about a year not very intensely.

I've read a lot about Snow Leopard and Grand Central Dispatch in particular. I'm aware that it uses blocks, but I've not got into the nitty gritty of how blocks work or how Grand Central Dispatch works.

My Question

How do I best develop one code base for both Snow Leopard and Leopard, whilst taking advantage to the most degree possible of the new multi threading stuff in Snow Leopard?

NSOperationQueue

My instinct is not to deal with GCD directly in my code, but when things need putting on a Queue, use NSOperationQueue, since I've read from Mike Ashes Q&A sessions that in Snow Leopard, NSOperationQueue takes full advantage of GCD and the crasher he discovered in Leopard has now been fixed.

Manual Thread Management

However, when it comes to managing specific background threads, is there any way to take advantage of the easier to use thread management stuff in Snow Leopard without breaking things in Leopard? Or would people recommend I have different targets for each OS with some different classes in each? This to me would seem like a maintenance nightmare just waiting to happen.

Or maybe I should just live with not having my app optimised fully for Snow Leopard and stick with +(void)detachNewThreadSelector:toTarget:withObject: or something similar.

What do people think?

+9  A: 

Your gut impression on GCD is correct. In fact, any API that uses blocks is out, unless you conditionalize that code to run on only on Snow Leopard. That makes sense if the code is to support features that are only available on Snow Leopard, but if it is a feature you also going to support on Leopard you might as well just use the Leopard code path in all cases, adding a Snow Leopard specific path that does not provide any visible improvement to the user is just going to complicate your code and increase your testing overhead.

This goes especially for things like thread management or GCD. Changes there require significant re architecture, it isn't simply:

if (snowLeopard) {
  [NSSnazySnowLeopardClass doSomething];
} else {
  [NSBoringLeopardClass doSomethingEquivalent];
}

In general if the changes are that simple Apple handles them inside the class without changing the API. In other words, the question isn't whether you can use the easier thread management code in Snow Leopard, it is why should you when you are going to need to do the hard version for Leopard anyway. An extra code path is an extra code path, and until you can drop Leopard support using significantly different APIs on Snow Leopard (even if they are easier to use than Leopard's) are just extra work.

I would think about whether you really want to target Leopard. Snow Leopard adoption has been fairly, Snow Leopard is a cheap upgrade, and because of the API changes there will be a lot of forward pressure on users from small developers doing Snow Leopard only apps. The only group of users that are going to stay on Leopard for a long time are those who are not technically savvy (who are unlikely to install much 3rd party software), and those still using PPC Macs (who haven't bought a new Mac in 3 years, so probably aren't buying much software). If it is an app you think is going to ship in 3-9 months I would argue that going Snow Leopard only is probably a reasonable option and will greatly cut down on your development and testing burden.

Louis Gerbarg
Thanks for this superb answer, Louis. I'm targeting Web developers with my application and several of my very early testers are already using Snow Leopard, indicating that I might well be better off making it Snow Leopard only. However, I'm currently developing on a PowerPC Mac and one of my testers is on PPC as well, which complicates things somewhat. I need to think carefully about where I go from here. Separate code paths is definitely out though. Thanks again for your answer.
John Gallagher
+2  A: 

One way would be to understand what APIs in Leopard have been modified in Snow Leopard to use GCD. For example, NSOperation and NSOperationQueue in Leopard work as they always have. However in Snow Leopard, they've been rewritten to take advantage of GCD underneath. Voilá. Instant upgrade for your 10.6 users.

Another option would be to use something like PLBlocks and compile GCD into your code yourself. I have no idea if that'll work, but it might be worth a shot. =)

Dave DeLong
I did come across PLBlocks, but I don't think trying to cram this into Leopard is workable. Thanks for the suggestion, anyway!
John Gallagher