正确的类集群的子类化

时间:2014-02-23 15:28:07

标签: ios objective-c

在观看iOS技术讲座并阅读类集群后,我决定将旧版iOS 6代码提取到私有子类:

@interface MyUIView : UIView @end           // public
@interface MyUIViewiOS6 : MyUIView @end     // private
@interface MyUIViewiOS7 : MyUIView @end     // private

@implementation MyUIView
+ (id)alloc
{
    // Don't loop on [super alloc]
    if ([[self class] isSubclassOfClass:[MyUIView class]] &&
        ([self class] != [MyUIViewiOS6 class]) &&
        ([self class] != [MyUIViewiOS7 class]))
    {
        if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) {
            return [MyUIViewiOS6 alloc];
        } else {
            return [MyUIViewiOS7 alloc];
        }
    }

    return [super alloc];
}
// Common implementation
@end

@implementation MyUIViewiOS6
// Legacy code
@end


@implementation MyUIViewiOS7
// iOS specific code
@end

这个实现很有效,直到我想要子类MyUIView。例如,如果我创建一个子类:

@interface MyRedUIView : MyUIView @end

然后按原样启动它:

[[MyRedUIView alloc] init]

将分配MyUIViewiOS6或MyUIViewiOS7类型的对象。有没有办法可以调整这种模式来支持子类化,以便MyRedUIView的超类动态切换到MyUIViewiOS6或MyUIViewiOS7?

1 个答案:

答案 0 :(得分:2)

你已经达到了经典的双继承问题。您希望成为RedUIViewGreenUIView,并且可以是MyUIViewiOS6MyUIViewiOS7视图。

由于objective-c不支持双重继承,因此您必须决定自己的行为和行为方式之间的区别。任何决定你是什么的东西,你都会上课。任何决定你行为的东西都会进入@protocol然后才能实现。

我会继承MyUIView,因为MyUIViewiOS6MyUIViewiOS7对应于您的身份,然后针对某些功能实施RedGreen协议:< / p>

@interface MyRedUIView : MyUIView<RedProtocol> @end

您可以检查此类是否符合特定协议:

 if ([class conformsToProtocol:@protocol(RedProtocol)]) {
    self.color = [UIColor redColor];
 }

如果他们 真的 都是你,那么你必须使用四个不同的类。


以下是使用类别的示例。假设您在问题中指定了MyUIView:

<强> GreenView.h

#import "MyUIView.h"
#import "Green.h"

@interface MyUIView (GreenUIView) <Green>

-(BOOL) isGreen;

@end

@interface GreenView : MyUIView @end

<强> GreenView.m

#import "GreenView.h"

@implementation MyUIView (GreenUIView)

-(BOOL) isGreen{
    return [self conformsToProtocol:@protocol(Green)];
}
@end

@implementation GreenView @end

<强> Green.h

@protocol Green <NSObject> @end

<强> AppDelegate.m

#import "GreenView.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    GreenView* view = [[GreenView alloc] init];
    NSLog(@"%@", [view isGreen]?@"yes":@"no");
    return YES;
}

@end