Ну, вы работаете с 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