Reputation: 4271
Let's say I have defined a protocol for a subclassed UIView
as follows:
@protocol MyCustomViewDelegate <NSObject>
- (NSString*) titleForItemAtIndex;
- (UIImage*) imageForItemAtIndex;
@end
I would want the class implementing the delegate methods to implement only one, and not both the delegate methods. If the delegate implements titleForItemAtIndex
, it must NOT implement imageForItemAtIndex
, and vice versa. The compiler must throw a warning (or some other way to communicate to this to the programmer) if both methods are implemented by the delegate class. Is that possible?
Upvotes: 0
Views: 91
Reputation: 26383
You can ask if the the delegate instance responds to a specific selector:
if ([self.delegate respondToSelector:@selector(titleForItemAtIndex)]) {
NSString * title = [title titleForItemAtIndex];
}
else if ([self.delegate respondToSelector:@selector(imageForItemAtIndex)]) {
UIImage * title = [title imageForItemAtIndex];
}
This will also require that you mark your delegate methods as @optional
in the protocol declaration. With this condition you guarantee that the first method has the precedence on the second.
You can add one more else
and throw an exception if none of them is called.
Upvotes: 4
Reputation: 6282
I dont think its possible to throw compiler errors. But still exceptions can be raised at runtime. You can use NSAssert
and make sure that only one method is implemented at run time. This does not throw a compiler error but causes the app to crash with a log saying that only one method should be implemented.
// Checks for titleForItemAtIndex
if ([self.delegate respondToSelector:@selector(titleForItemAtIndex)])
{
// Delegate has implemented titleForItemAtIndex.
// So it should not be implementing imageForItemAtIndex
// Below assert will check this
NSAssert(![self.delegate respondToSelector:@selector(imageForItemAtIndex)], @"Delegate must not respond to imageForItemAtIndex");
// Now that condition is checked. Do anything else as needed below.
}
// Checks for imageForItemAtIndex
if ([self.delegate respondToSelector:@selector(imageForItemAtIndex)]) {
// Delegate has implemented imageForItemAtIndex.
// So it should not be implementing titleForItemAtIndex
// Below assert will check this
NSAssert(![self.delegate respondToSelector:@selector(titleForItemAtIndex)], @"Delegate must not respond to titleForItemAtIndex");
// Now that condition is checked. Do anything else as needed below.
}
Another approach would be to create separate protocols for both methods, and use the same if assert
condition but with conformsToProtocol
If you have a lot of mutually exclusive methods, its better to create separate protocols.
Upvotes: 1