Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective C protocols requiring the implementation of at least one of a set of methods

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.

like image 212
jbat100 Avatar asked Nov 06 '11 18:11

jbat100


People also ask

What are protocols in Objective-C?

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.

How protocols are implemented in Java?

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.

Do we need to declare the protocol methods in the class?

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:

What is the difference between a class interface and protocol?

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.


2 Answers

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
like image 90
Chuck Avatar answered Oct 07 '22 00:10

Chuck


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
like image 28
justin Avatar answered Oct 07 '22 01:10

justin