Q:

Conditionally overriding a system method via categories in Objective-C?

Is there a way to provide a method implementation (that bears the exact same name of a method defined by the framework) only when the method isn't already defined in the system?  For example method [NSSomeClass someMethod:] exists only in Mac OS X 10.6 and if my app runs in 10.5, I will provide that method's definition in a category.  But when the app runs in 10.6, I want the OS-provided method to run.
Background: I'm creating an app targeted for both 10.5 and 10.6.  The problem is that I recently realized that method +[NSSortDescriptor sortDescriptorWithKey:ascending:] only exists in 10.6 and my code is already littered by that method call.  I could provide a default implementation for it (since this time it's not too difficult to implement it myself), but I want the "native" one to be called whenever my app runs on 10.6.  Furthermore if I encounter similar problems in the future (with more difficult-to-implement-myself methods), I might not be able to get away with providing a one-liner replacement.
This question vaguely similar to Override a method via ObjC Category and call the default implementation? but the difference is that I want to provide implementations only when the system doesn't already have one.
Thanks.

A:

I would compile +[NSSortDescriptor sortDescriptorWithKey:ascending:] in a category into a separate bundle. Then at the very beginning of your main, check if the NSSortDescriptor class has the sortDescriptorWithKey:ascending: method with respondsToSelector:. If it's not implemented (i.e. you are running on < 10.6), then load the bundle with -[NSBundle loadAndReturnError:].
This way, you will run the OS-provided method on 10.6 and your implementation on 10.5.

A:

Yes, this is possible. Since you are targetting 10.5+ I'm assuming you are using the ObjC2 runtime, which makes it fairly straightforward.
The Objective-C Runtime Reference has all the methods you will need. Specifically, you can use class_getClassMethod or class_getInstanceMethod to see if the method already exists, and then class_addMethod to bind your implementation to that selector if the class doesn't already have it.

