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

时间:2013-12-05 01:08:21

标签: objective-c delegates selector protocols respondstoselector

当想要在委托对象上调用协议方法时,希望实现相应的协议方法,我看到开发人员首先检查

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

这样做不是更好甚至更安全吗? :

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

我知道如果协议方法定义已经正确地构造,那么代理中永远不应该有任何冲突或实现,这些冲突或实现可能不适合/来自MyProtocol。这样的冲突很遥远,但我遇到了一个简单声明为 - (void)willStartLogin;的协议方法定义。我相信你已经可以开始思考并建议这样的协议方法是如何坏的,例如它可以由代表实现个人/内部使用,而不是在myDelegate协议下使用。最好将MyProtocol的方法声明为: - (void)myObjectWillStartLogin:(MyObject *)myObjectInstance;这样可以摆脱任何歧义,使事情变得明显。

我希望我不会错过任何只需要检查respondsToSelector的内容: 谢谢

2 个答案:

答案 0 :(得分:7)

我不确定你在问什么,但也许这会有所帮助:

协议是一组方法,一些是必需的,一些是可选的。 conformsToProtocol:回答的问题是对象声称是否实现了一系列方法 - 必需的方法 - 并且可以实现其他方法 - 可选方法。请注意,这里声明,而不是 ,因为无法实现所需的方法不会阻止编译(这只是一个警告)。

respondsToSelector:回答的问题是对象是否实现了特定方法。与conformsToProtocol:不同,这为此特定方法提供了明确的答案。

respondsToSelector:的确定性质是它常用的原因。

您可能认为除了方法之外检查协议更好,因为它意味着该方法更有可能达到您的预期,如果是这样,同时使用respondsToSelector:conformsToProtocol:告诉您你得到的答案......有点 - 因为协议实际上只是方法名称和签名,这些方法的行为是暗示而不是强制执行(*)。

HTH。

(*如果你想要强制执行合同,例如,埃菲尔)

答案 1 :(得分:4)

如果一个对象绝对必须符合协议,那么你应该这样声明你的对象:

id<MyProtocol> delegate;

这会为尝试将不符合MyProtocol协议的对象分配给变量/ parameter / property delegate的任何人生成编译时错误。 (他们可以使用显式转换来绕过警告,但是他们应该聪明地做到这一点。)

您仍然需要检查respondsToSelector,以防delegate响应选择器,因为它可能有多种方式。 (帽子提示:@Hot Licks)