簡體   English   中英

正確的類集群的子類化

[英]Proper subclassing of class clusters

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

你已經達到了經典的雙繼承問題。 您想要成為RedUIViewGreenUIView並且可以是MyUIViewiOS6MyUIViewiOS7視圖。

由於objective-c不支持雙重繼承,因此您必須決定自己的行為和行為方式之間的區別。 任何決定你是什么的東西,你都會上課。 任何決定你行為的東西都會進入@protocol然后才能實現。

我會將MyUIView子類MyUIView因為MyUIViewiOS6MyUIViewiOS7對應於你是誰,然后為某些功能實現RedGreen協議:

@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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM