如何在Obj-C中检查一个类是否实现了协议中的所有方法?

4
如果一个对象符合Objective-C中的某个协议,是否有一种方法可以检查它是否符合该协议中的所有方法。我宁愿避免明确检查每个可用方法。谢谢。

2
协议方法默认是必需的,因此如果一个类采用了给定的协议,它应该实现所有那些没有标记为“@optional”的方法。 - Caleb
1
@NoahWitherspoon 我不是在问如何检查协议的一致性,我是在问如何检查实际协议中的方法是否都已经被实现了。 - Christian Gossain
2
也许可以通过循环调用协议中每个方法的respondsToSelector来实现。要获取协议的方法,请查看此链接https://dev59.com/7HI95IYBdhLWcg3w7CfL - Johnmph
2
这不是重复内容。它是关于检查类是否实际实现了协议中声明的方法。 - Sebastian
1个回答

5

使用 protocol_copyMethodDescriptionList 可以获取协议中声明的所有方法, 它返回一个指向 objc_method_description 结构体的指针。

objc_method_descriptionobjc/runtime.h 中定义:

struct objc_method_description {
    SEL name;               /**< The name of the method */
    char *types;            /**< The types of the method arguments */
};

要查找类的实例是否响应一个选择器,请使用instancesRespondToSelector:

这将使您拥有以下函数:

BOOL ClassImplementsAllMethodsInProtocol(Class class, Protocol *protocol) {
    unsigned int count;
    struct objc_method_description *methodDescriptions = protocol_copyMethodDescriptionList(protocol, NO, YES, &count);
    BOOL implementsAll = YES;
    for (unsigned int i = 0; i<count; i++) {
        if (![class instancesRespondToSelector:methodDescriptions[i].name]) {
            implementsAll = NO;
            break;
        }
    }
    free(methodDescriptions);
    return implementsAll;
}

1
如果类没有实现协议的所有方法,则会发生内存泄漏,请在返回 NO 之前添加 free(methodDescrptions);,或者更好地,当未找到时添加标志并中断循环。 - Johnmph
伙计们,一个词...牛逼。感谢Sebastian提供这个精彩的答案,也感谢@Johnmph的跟进评论。 - Christian Gossain
@Johnmph 谢谢,发现得好!我更新了我的答案,只有一个返回语句。 - Sebastian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接