ios – 类集群的正确子类化

在观看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?

最佳答案 你已经达到了经典的双继承问题.您想要成为RedUIView或GreenUIView,并且可以是MyUIViewiOS6或MyUIViewiOS7视图.

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

我会将MyUIView子类化,因为MyUIViewiOS6和MyUIViewiOS7对应于你是谁,然后为某些功能实现Red或Green协议:

@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
点赞