Objective-c为旧设备添加对新类的支持

时间:2012-10-26 10:19:27

标签: objective-c ios5 ios6 runtime

问题:每个新iOS都会添加许多新的有用类。例如,UIRefreshControl。我想在iOS5版本中添加对这个类的支持。

不酷的解决方案:在所有必须使用UIRefreshControl的类中,我可以检查当前的iOS版本并使用内联替换这些类,例如:

pseudocode
...

- (void)viewDidLoad
{
    ...

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

这个解决方案并不酷,因为我必须在我想要使用最新iOS功能的所有类中添加相同的代码。

可能很酷的解决方案: 1)获取或创建自己的100%兼容类,例如对于UIRefreshControl,您可以使用CKRefreshControl(https://github.com/instructure/CKRefreshControl); 2)使用Objective-C运行时在App启动时将替换类定义为主类。

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);
    }

    ...
}

我认为这种方式真的很酷,但这段代码不起作用。

4 个答案:

答案 0 :(得分:0)

您可能希望使用不同的方式创建一个一致的界面。您需要strategy design pattern来解决问题。然后你需要只检查一次版本 - 在初始化对象时进行iOS版本的特定工作。

答案 1 :(得分:0)

如果所有方法调用都相同(并且没有类/“静态”方法),只需使用“工厂”方法创建对象,然后“正常”使用它们。

否则,我可能会使用一个“包装器”类,根据Filip的帖子之一重新调用内置支持或“替换”的调用。

答案 2 :(得分:0)

第二个灵魂应该工作正常 启用 ARC 时可能会出现一些问题,因此,您应该将allocate_pair代码移动到某个类,该类使用-fno-objc-arc标志进行编译

有关更多信息,请查看此处(在评论中):
http://www.mikeash.com/pyblog/friday-qa-2010-11-6-creating-classes-at-runtime-in-objective-c.html

答案 3 :(得分:0)

@abuharsky,[CKRefreshControl] https://github.com/instructure/CKRefreshControl已更新,现在完全符合您的要求。您所需要做的就是:

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

如果这对您不起作用,请告诉我们。