【问题标题】:Objective-c add support for new classes to old devicesObjective-c 为旧设备添加对新类的支持
【发布时间】:2012-10-26 10:19:26
【问题描述】:

问题:每个新的 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)App启动时使用Objective-C运行时定义替换类为主类。

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

    ...
}

我觉得这种方式很酷,但是这段代码行不通。

【问题讨论】:

    标签: objective-c ios5 ios6 runtime


    【解决方案1】:

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

    【讨论】:

    • 不是Objective-c或者cocoa风格,java中经常使用这种方式。
    • 这是一种可以在Objective-C中使用的设计模式。面向对象的应用程序设计原则和模式也适用于 Objective-C 编程。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      有关更多信息,请查看此处(以 cmets 为单位):
      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 已更新,现在完全符合您的要求。您需要做的就是:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-06-26
          • 1970-01-01
          相关资源
          最近更新 更多