Search code examples
objective-cdelegatesselectorprotocolsrespondstoselector

( ConformsToProtocol: && RespondsToSelector: ) vs just ( respondsToSelector: )


When wanting to call a protocol method on a delegate object that, hopefully, implements the respective protocol method, I see developers first checking

if([delegate respondsToSelector: @selector(aMethod)])
    {
        //send message;
    }

Is it not better or even safer to do this instead ? :

if([delegate conformsToProtocol:@protocol(MyProtocol)] && [delegate respondsToSelector: @selector(aMethod)])
    {
        //send message;
    }

I know that if the protocol method definitions have been structured properly then there should never be any conflicts or implementations in the delegate that may not be intended for / come from MyProtocol. Such conflicts are far fetched but I have come across a protocol method definition simply declared as -(void)willStartLogin;. Im sure you can already start thinking and suggesting how such a protocol method is bad, it could for example have been implemented by the delegate for personal / internal use and not for use under the myDelegate protocol. It would be better to declare MyProtocol's method as so: -(void)myObjectWillStartLogin:(MyObject*)myObjectInstance; so as to get rid of any ambiguity and make things obvious.

I hope I am not missing anything that makes it only necessary to check respondsToSelector: Thank you


Solution

  • If an object absolutely must conform to a protocol, then you should declare your object this way:

    id<MyProtocol> delegate;
    

    This will generate compile-time errors for anyone trying to assign an object that doesn't conform to the MyProtocol protocol to the variable/parameter/property delegate. (They can use an explicit cast to get around the warning, but it's up to them to do that intelligently.)

    You still need to check respondsToSelector, just in case delegate will respond to the selector, since there are a number of ways it might not. (Hat tip:@Hot Licks)