Proper subclassing of class clusters

After looking at the technical discussions of iOS and reading class clusters, I decided to extract the obsolete iOS 6 code into a private subclass:

@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

This implementation works well until I want to subclass MyUIView. For example, if I create a subclass:

@interface MyRedUIView : MyUIView @end

and then do it like this:

[[MyRedUIView alloc] init]

an object of type MyUIViewiOS6 or MyUIViewiOS7 will be assigned instead. Is there a way I can adapt this template to support a subclass so that the superclass MyRedUIView dynamically switches to MyUIViewiOS6 or MyUIViewiOS7?

+4
source share
1 answer

. 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
+2

All Articles