How to create a protocol with methods that are optional?
Use the @optional
keyword before your method declaration to make it optional. Simple as that!
// myProtocol.h
@protocol myProtocol
- (void)myMandatoryMethod:(id)someArgument;
@optional
- (void)myOptionalMethod:(id)someArgument;
@end
// myClass.m
@interface myClass : someSuperClass <myProtocol>
//...
@end
Protocols is set of rules. We can create protocols as below example:
TestProtocols.h
@protocol TestProtocols <NSObject>
@optional
-(void)testMethodOptional;
@required // by default
-(void)testMethodRequired;
@end
Implementation:
TestClass.h
#import "TestProtocols.h"
@interface TestClass : NSObject <TestProtocols>
@end
TestClass.m
#import "TestClass.h"
@implemenation TestClass
//optional to implement
-(void)testMethodOptional{
// Your Code
}
//required to implement
-(void)testMethodRequired{
// Your Code
}
@end
From the Apple page on "Formal Protocols":
Optional Protocol methods can be marked as optional using the @optional keyword. Corresponding to the @optional modal keyword, there is a @required keyword to formally denote the semantics of the default behavior. You can use @optional and @required to partition your protocol into sections as you see fit. If you do not specify any keyword, the default is @required.
@protocol MyProtocol
- (void)requiredMethod;
@optional
- (void)anOptionalMethod;
- (void)anotherOptionalMethod;
@required
- (void)anotherRequiredMethod;
@end
If a method in a protocol is marked as optional, you must check whether an object implements that method before attempting to call it.
As an example, the pie chart view might test for the segment title method like this:
NSString *thisSegmentTitle;
if ([self.dataSource respondsToSelector:@selector(titleForSegmentAtIndex:)]) {
thisSegmentTitle = [self.dataSource titleForSegmentAtIndex:index];
}
The respondsToSelector: method uses a selector, which refers to the identifier for a method after compilation. You can provide the correct identifier by using the @selector() directive and specifying the name of the method.
If the data source in this example implements the method, the title is used; otherwise, the title remains nil.