If you expand the question from simple swizzling to actually modifying the library, I can come up with useful examples.
As in iOS 5, NSURLConnection provides sendAsynchronousRequest:queue:completionHandler: which is a lock (/ close) method for performing asynchronous loading from any resource identified by a URL (local or remote). This is a very useful way, as it makes your code cleaner and smaller than the classic delegate, and it is much more likely that the related parts of your code will be close to each other.
This method is not provided in iOS 4. So I did in my project that when I start the application (via the appropriate + (void)load ) I check if the method is defined. If I do not fix its implementation on the class. From now on, every other part of the program can be written into the iOS 5 specification without any verification of version or accessibility, just as if I focused only on iOS 5, except that it will also work on iOS 4.
In Java or C ++, I assume that the same kind of thing will be achieved by creating your own class to send URL connections that perform runtime checks on every call. This is the worst decision, because it is difficult for him to retreat. So, if I decided one day to support iOS 5, I just delete the source file, which adds my implementation of sendAsynchronousRequest:... Nothing changed.
As for the swizzling method, the only thing I see in it is that someone wants to change the functionality of an existing class and does not have access to the code in which the class is created. Thus, you usually talk about trying to change a logically opaque code from the outside, making assumptions about its implementation. I would not support this as an idea in any language. I assume it is more recommended in Objective-C, because Apple is more inclined to make things opaque (see, for example, every application that wants to show a customized camera view prior to iOS 3.1, every application that wants to execute a custom processing on camera input earlier to iOS 4.0, etc.), but not because it is a good idea in Objective-C. This is not true.
EDIT: so in the rest of the presentation, I cannot publish the full code because I wrote it as part of my work, but I have a class called NSURLConnectionAsyncForiOS4 with an implementation of sendAsynchronousRequest:queue:completionHandler: This implementation is actually quite trivial, just sending the operation to the designated queue, which performs the synchronous load through the old sendSynchronousRequest:... interface, and then sends the results from this to the handler.
This class has + (void)load , which is the method of the class that you add to the class, which will be released immediately after this class has been loaded into memory, effectively as a global constructor for the metaclass and with all the usual caveats.
In my +load I use the Objective-C runtime directly through my C interface to check if sendAsynchronousRequest:... is NSURLConnection on NSURLConnection . If this is not the case, I add my implementation to NSURLConnection , so it is now defined. This is clearly not swizzling - I am not adjusting the existing implementation of anything, I just add a custom implementation of something if Apple is not available. Corresponding runtime calls are objc_getClass , class_getClassMethod and class_addMethod .
In the rest of the code, when I want to make an asynchronous URL connection, I just write, for example.
[NSURLConnection sendAsynchronousRequest:request queue:[self anyBackgroundOperationQueue] completionHandler: ^(NSURLResponse *response, NSData *data, NSError *blockError) { if(blockError) {
So, the rest of my code is just written in the iOS 5 API and doesnβt know or care that I have a gasket somewhere else to ensure that one microscopic part of iOS 5 changes to iOS 4. And, as I already said when I stop supporting iOS 4, I just remove the gasket from the project and the rest of the code will continue to not know and not care.
I had similar code to provide an alternative partial implementation of NSJSONSerialization (which dynamically created a new class at runtime and copied it); one tweak you need to make is that links to NSJSONSerialization elsewhere will resolve once during linker loading, which you really don't want. So I added a quick #define from NSJSONSerialization to NSClassFromString(@"NSJSONSerialization") in my precompiled header. Which is less functionally neat, but a similar course of action in terms of finding a way to support iOS 4 support so far is simply writing the rest of the project to iOS 5 standards.