R – One code base for Snow Leopard and Leopard

cocoagrand-central-dispatchobjective-cosx-snow-leopard

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?

Best Solution

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.

Related Question