Objective-c add support for new classes to old dev

2019-08-09 04:10发布

问题:

The problem: every new iOS adds a lot of new useful classes. For example, UIRefreshControl. I want to add support for this class in iOS5 build.

Not cool solution: In all classes that must use UIRefreshControl, I can check for current iOS version and use inline replacement for that classes, for example:

pseudocode
...

- (void)viewDidLoad
{
    ...

    if([[UIDevice currentDevice].systemVersion floatValue] < 6.0)
    {
        self.refreshControl = [[MyCustonRefreshControl_for_iOS5 alloc] init];
    }
    else
    {
        self.refreshControl = [[UIRefreshControl alloc] init];
    }
    ...
}

This solution is't cool, because I must add same code in all classes where I want to use latest iOS features.

Possible cool solution: 1) get or create your own 100% compatible class, for example for UIRefreshControl you can use CKRefreshControl (https://github.com/instructure/CKRefreshControl); 2) use Objective-C runtime to define replacement class as main class when App starts.

pseudocode
...

// ios 5 compatibility
#include <objc/runtime.h>
#import "CKRefreshControl.h"
...



- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    ...

    // pre-ios 6 compatibility
    if([[UIDevice currentDevice].systemVersion floatValue] < 6.0)
    {
        // register refresh control
        Class clazz = objc_allocateClassPair([CKRefreshControl class], "UIRefreshControl", 0);
        objc_registerClassPair(clazz);
    }

    ...
}

I think that this way is really cool, but this code won't work.

回答1:

You may want to make one consistent interface with different ways of doing the job. You need a strategy design pattern to solve your problem. Then you need to check for version only once - at initialisation of object which is doing iOS version specific job.



回答2:

If all method calls are identical (and no class/"static" methods to speak of), simply use a "factory" method to create the objects and then use them "normally".

Otherwise, I'd probably use a "wrapper" class that reroutes calls to either the builtin support or your "replacement", based on one of the tests Filip's post.



回答3:

The second soultion should work fine
There's can be some issues when ARC is enabled, so, you should move allocate_pair code to some class, that is compiled with -fno-objc-arc flag

For more information, look here (in comments):
http://www.mikeash.com/pyblog/friday-qa-2010-11-6-creating-classes-at-runtime-in-objective-c.html



回答4:

@abuharsky, [CKRefreshControl]https://github.com/instructure/CKRefreshControl has been updated and now does exactly what you are asking for. All you need to do is:

self.refreshControl = [[UIRefreshControl alloc] init];

Let us know if that doesn't work for you.