In Objective C, protocol methods can be required or optional:
@protocol AProtocol
@required
-(void) aRequiredMethod;
@optional
-(void) anOptionalMethod;
@end
Is there an elegant way to say the object conforming to the protocol has to respond to at least one of a set of methods, my dream would be something like
@protocol AProtocol
@anyof
-(void) onePossibleMethod;
-(void) anotherPossibleMethod;
@optional
-(void) anOptionalMethod;
@end
EDIT:
This being (as far as I know), impossible, would there be a way to raise a compile time warning if a class declared as conforming to a given protocol made entirely of optional methods
@protocol AProtocol
@optional
-(void) onePossibleMethod;
-(void) anotherPossibleMethod;
@end
failed to implement at least one of them.
In Objective-C, a protocol is a group of methods that can be implemented by any class. Protocols are essentially the same as interfaces in C#, and they both have similar goals.
Protocols are implemented in the classes conforming to protocol. For instance, a network URL handling class, it will have a protocol with the methods like processCompleted delegate method that intimates the calling class when the network URL fetching operation is completed.
And there is no need to re-declared the protocol methods in the class interface. Here is an example program, demonstrates the concept of protocol in Objective-C:
A class interface declares the methods and properties associated with that class. A protocol, by contrast, is used to declare methods and properties that are independent of any specific class. Protocols can include declarations for both instance methods and class methods, as well as properties.
There isn't a great way to express this in Objective-C. If you must do this, IMO the most idiomatic and least code-bloating way is something along these lines:
@protocol AProtocol
@required
- (SEL)methodToUse; // returns one of "onePossibleMethod" or "anotherPossibleMethod"
@optional
-(void) onePossibleMethod;
-(void) anotherPossibleMethod;
-(void) anOptionalMethod;
@en
Well, you are working with ObjC, so you will need to exercise some restraint yourself:
@protocol MONAbstractDataProvider
@optional
- (void)anOptionalMethod;
@end
@protocol MONDataProviderA < MONAbstractProvider >
@required
- (void)onePossibleMethod;
@end
@protocol MONDataProviderB < MONAbstractProvider >
@required
- (void)anotherPossibleMethod;
@end
In that case, you'll have to do a confromsToProtocol:
test at the callsite, rather than respondsToSelector:
test for onePossibleMethod
and anotherPossibleMethod
. Then you pass MONAbstractDataProvider
around. That can introduce some type safety, as long as you remember the rules, but it is really only slightly better than the customary approach.
So the client side would look like this:
- (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");
}
}
That of course assumes the client knows about all of the derivatives.
You may instead prefer the simpler singular approach if they are both void
:
@protocol MONAbstractDataProvider
@required
- (void)performPossibleMethod;
@optional
- (void)anOptionalMethod;
@end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With