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