Tuesday, July 05, 2011

The Reason Why an Objective-C Protocol Doesn't Implement respondsToSelector:

I've been having a lot of fun with Objective-C protocols lately. In one of the projects I'm on, I've been working to eliminate warnings from the compiler. One of those warnings is that respondsToSelector: isn't found in your delegate or data source. When working with a delegate or data source, two different naming conventions for Objective-C protocols, a typical pattern your code follows is to see if your delegate or data source actually implements a method defined in your protocol, like this:
- (void)notifyDelegateOfButtonTap
    if (self.delegate &&
       [self.delegate respondsToSelector:@selector(protocolSampleViewController:didTapButton:)])
        [self.delegate protocolSampleViewController:self didTapButton:self.button];
The protocol definition would typically look like this when implementing this pattern:
@protocol ProtocolSampleViewControllerDelegate
- (void)protocolSampleViewController:(ProtocolSampleViewController *)protocolSampleViewController didTapButton:(UIButton *)button;
This is a typical protocol definition as code completed in Xcode 3.x, with the addition of @optional just to maintain pattern correctness for the example. In Xcode 4.x, the code completed @protocol definition template looks like this:
@protocol protocol name <NSObject>
As you might have guessed by now, the <NSObject> added behind the protocol name is the key. That's because it's actually the NSObject protocol that defines most of the core methods that the NSObject class implements, including respondsToSelector:

Once you make sure all your protocol definitions adopt the <NSObject> protocol, then calling respondsToSelector: on your delegate or datasource variables won't result in compiler warnings.

One more thing...you could cast your delegate or data source variable to id like this:
[(id)self.delegate respondsToSelector:@selector(protocolSampleViewController:didTapButton:)]
That is an ugly solution and doesn't help you understand another key feature of protocols, inheritance, which I plan to cover in an upcoming post.