在我希望将一个类打算成为基类的场景中,考虑到需要实现其子子句指向的某些基本行为,我想出了这个:
协议
@protocol TheProtocol
@required
- (NSString *)someProperty;
- (void)someMethod:(NSString *)parameter;
@end
基本视图控制器
@interface BaseViewController : UIViewController
@end
@implementation BaseViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSAssert([self conformsToProtocol:@protocol(TheProtocol)], @"This view controller has to conform to TheProtocol.");
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
BaseViewController<TheProtocol> *castedController = (BaseViewController<TheProtocol> *)self;
NSString *someProperty = [castedController someProperty];
NSLog(@"%@", someProperty);
[castedController someMethod:@"Hello subclass!"];
}
@end
实施协议的控制器示例
@interface Subclass1ViewController : BaseViewController <TheProtocol>
@end
@implementation Subclass1ViewController
#pragma mark - TheProtocol
- (NSString *)someProperty {
return @"Subclass1";
}
- (void)someMethod:(NSString *)parameter {
NSLog(@"%@", parameter);
}
@end
这种模式是否正确?我有很多顾虑......另一种选择是创建受保护的类别而不是协议。
答案 0 :(得分:1)
你的模式是对的。
这里只是与你的想法完全相似的解决方案,但我个人会在我的项目中为了达到同样的目的而这样做 - 所以我不需要在课堂上投射BaseClass
的实例,因为在我的想法中,基类基本上符合基本的DemandedProtocol
,但在每个必需的方法中抛出一个运行时异常,该方法尚未在子集中被覆盖但是试图被调用。
注意:这并不比你的更差或更好,但不同,任何人都可以将其用于教育目的。
@protocol DemandedProtocol <NSObject>
@required
- (NSString *)someString;
- (void)setSomething:(id)something;
@optional
- (NSInteger)someInteger;
@end
#import "DemandedProtocol.h"
#define ThrowOverrideIsMissingException @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"%s has to be overridden in subset.", __func__] userInfo:nil]
@interface BaseClass : NSObject <DemandedProtocol> {
}
@end
#import "BaseClass.h"
@implementation BaseClass
#pragma mark - <DemandedProtocol>
- (NSString *)someString {
ThrowOverrideIsMissingException;
}
- (void)setSomething:(id)something {
ThrowOverrideIsMissingException;
}
@end