objective-cobjective-c-protocol

Defining a protocol to require one method only if another is implemented


I've got a fairly complicated protocol which I'm adding methods to. Most of the new methods are @optional, but they are paired.

For example, these two methods work together:

@optional
   - (BOOL) shouldIDoSomethingHere;
   - (CGPoint) whereShouldIDoIt;

In this example, if the first method is implemented, I want to declare the second method as @required, otherwise both are optional. What I want is a way to nest or group protocol methods as either all required or not based on context.

Ideally something like:

@optional
    @required
    - (BOOL) shouldIDoSomethingHere;
    - (CGPoint) whereShouldIDoIt; 
    @endRequired 
    //... next optional method

Solution

  • There is no way to enforce this at compile-time. Your best bet is, at runtime, when the your delegate property is set (or whatever you use to refer to the object implementing the protocol), just go ahead and implement whatever conformance rules you need there using -respondsToSelector: and throw an exception immediately if the object doesn't conform to your rules. Something like:

    - (void)setDeleate:(id<MyDelegate>)delegate {
        if ([delegate respondsToSelector:@selector(shouldIDoSomethingHere)]) {
            NSAssert([delegate respondsToSelector:@selector(whereShouldIDoIt)], @"Delegate must respond to -whereShouldIDoIt if it responds to -shouldIDoSomethingHere");
        }
        // ...
        _delegate = delegate;
    }