在Objective C中,协议方法可以是必需的或可选的:
@protocol AProtocol
@required
-(void) aRequiredMethod;
@optional
-(void) anOptionalMethod;
@end
是否有一种优雅的方式可以说符合协议的对象必须至少响应一组方法中的一种,我的梦想就像
@protocol AProtocol
@anyof
-(void) onePossibleMethod;
-(void) anotherPossibleMethod;
@optional
-(void) anOptionalMethod;
@end
编辑:
这是(据我所知),不可能,如果声明符合完全由可选方法完成的给定协议的类,是否有办法提出编译时警告
@protocol AProtocol
@optional
-(void) onePossibleMethod;
-(void) anotherPossibleMethod;
@end
未能实施至少其中一项。
答案 0 :(得分:3)
嗯,你正在和ObjC一起工作,所以你需要自己克制一下:
@protocol MONAbstractDataProvider
@optional
- (void)anOptionalMethod;
@end
@protocol MONDataProviderA < MONAbstractProvider >
@required
- (void)onePossibleMethod;
@end
@protocol MONDataProviderB < MONAbstractProvider >
@required
- (void)anotherPossibleMethod;
@end
在这种情况下,您必须在呼叫网站进行confromsToProtocol:
测试,而不是respondsToSelector:
测试onePossibleMethod
和anotherPossibleMethod
。然后你绕过MONAbstractDataProvider
。这可以引入一些类型的安全性,只要你记住规则,但它实际上只比常规方法略好。
所以客户端看起来像这样:
- (void)update:(NSObject<MONAbstractDataProvider>*)provider
{
if ([provider conformsToProtocol:@protocol(MONDataProviderA)]) {
[(NSObject<MONDataProviderA>*)protocol onePossibleMethod];
}
else if ([provider conformsToProtocol:@protocol(MONDataProviderB)]) {
[(NSObject<MONDataProviderB>*)provider anotherPossibleMethod];
}
else {
assert(0 && "rule broken");
}
}
当然,假设客户知道所有衍生品。
如果它们都是void
:
@protocol MONAbstractDataProvider
@required
- (void)performPossibleMethod;
@optional
- (void)anOptionalMethod;
@end
答案 1 :(得分:3)
在Objective-C中没有很好的方法来表达这一点。如果你必须这样做,IMO最常用和最少代码膨胀的方式是这样的:
@protocol AProtocol
@required
- (SEL)methodToUse; // returns one of "onePossibleMethod" or "anotherPossibleMethod"
@optional
-(void) onePossibleMethod;
-(void) anotherPossibleMethod;
-(void) anOptionalMethod;
@en
答案 2 :(得分:0)
您可以拥有一个动态委托属性,该属性仅允许将委托分配给实现一个方法或另一个方法的类,但这些属性在运行时而不是在编译时。您还可以创建一个bash脚本,该脚本将检查是否已实现其中一个,并且是在编译时。