7

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

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 的东西:谢谢

4

2 回答 2

7

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

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

回答的问题respondsToSelector:是对象是否实现了特定的方法。与conformsToProtocol:.

的确定性respondsToSelector:是为什么它被普遍使用。

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

HTH。

(* 如果您想要强制执行的合同,请查看,例如埃菲尔)

于 2013-12-05T01:46:55.927 回答
4

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

id<MyProtocol> delegate;

对于任何试图将不符合MyProtocol协议的对象分配给 variable/parameter/property的人,这都会产生编译时错误delegate。(他们可以使用显式强制转换来绕过警告,但这取决于他们是否明智地做到这一点。)

您仍然需要检查respondsToSelector,以防万一delegate会响应选择器,因为有很多方法可能不会。(帽子提示:@Hot Licks)

于 2013-12-05T01:45:24.047 回答