I've been looking for a way to use optional protocol methods and have clean code. In other words:
1: No respondsToSelector:
calls all over my code
2. Should work for any method signature, so a category method on NSObject making the check and calling performSelector:
is out (and NSInvocation has problems cooperating with ARC)
3: This solution, IMO, pretends to be universal but has all the drawbacks of 1
I eventually came up with this idea:
@protocol MyProtocol <NSObject>
@optional
-(void)optionalMethod;
@end
@interface ClassA : NSObject <MyProtocol>
@end
@implementation ClassA
-(void)optionalMethod{
NSLog(@"ClassA implements optionalMethod");
}
@end
@interface ClassB : NSObject <MyProtocol>
@end
@implementation ClassB
//classB does not implement optionalMethod
@end
@interface NSObject (DefaultMyProtocolImplementation)
-(void)optionalMethod;
@end
@implementation NSObject (DefaultMyProtocolImplementation)
-(void)optionalMethod{
NSLog(@"%@ does not implement optionalMethod", NSStringFromClass([self class]));
}
@end
It seems to work, i.e.:
...
ClassA *objA = [[ClassA alloc] init];
ClassB *objB = [[ClassB alloc] init];
[objA optionalMethod]; //prints "ClassA implements optionalMethod"
[objB optionalMethod]; //prints "ClassB does not implement optionalMethod"
While many places online discuss this problem, I haven't stumbled upon this solution, which makes me think there's something wrong with it -- some major case where it will fail, or be unpredictable.
Should I just do it, or are my concerns valid?
[objectWhichDoesNotDeclareConformanceToTheProtocol theOptionalProtocolMethod];
This is actually how optional protocol methods were originally implemented: Informal protocol in ObjC The other thing is, methods that you add to framework classes should ideally be prefixed to avoid collisions. – Brentbrenton