【问题标题】:iPhone, is using isKindOfClass considered bad practice in any way?iPhone,是否以任何方式使用 isKindOfClass 被认为是不好的做法?
【发布时间】:2011-02-06 11:42:32
【问题描述】:

例如如果有一个'handle all'类型的方法...

if ([obj isKindOfClass:class1]) {
    // ...
} else if ([obj isKindOfClass:class2]) {
    // etc..

这是不好的做法吗?有没有更简洁的替代方案或更好的方法来构建代码?

在运行时、可读性、可维护性或其他方面是否存在劣势?

【问题讨论】:

    标签: objective-c cocoa cocoa-touch


    【解决方案1】:

    每当某件事被认为好的/坏的做法时,它或多或少都是主观的。当做某事本质上是正确/错误时,它或多或少是客观的。

    isKindOfClass: 是检查类继承的有用方法。它回答了唯一的问题,“一个类的对象是给定类的(子类)吗?”。它不回答任何其他问题,例如“此对象是否以自己的方式实现该方法?”或“我可以将对象用于 X 或 Y 吗?”。如果您按预期使用isKindOfClass:,则不会有任何问题。毕竟,在动态类型语言中,您应该有工具来提取有关对象的元信息。 isKindOfClass: 只是可用的工具之一。

    某些对象可能对它们的类​​撒谎这一事实不应该真的让你失望。他们只是将自己伪装成另一个类的对象而不会破坏任何东西。如果这不会破坏任何东西,我为什么要关心?

    最重要的是,您应该始终记住为任何特定目的使用正确的工具。例如,isKindOfClass: 不能替代 respondsToSelector:conformsToProtocol:

    【讨论】:

      【解决方案2】:

      有点。这个问题基本上涵盖了您要问的内容:Is it safe to use isKindOfClass: against an NSString instance to determine type?

      您需要牢记一些注意事项(请参阅上面的链接),但我个人认为这是一种相当易读的方法。您只需要确保您在条件测试中所做的事情是适当的(Apple 给出的示例类似于“一个对象可能它是一种 NSMutableArray,但你可能不是能够改变它”)。

      【讨论】:

        【解决方案3】:

        我认为您给出的示例是反模式,所以是的,我会说它是有害的。像这样使用 isKindOf 会破坏多态性和面向对象。

        我更希望你打电话:

        [obj doTheThing];
        

        然后在您的子类中以不同的方式实现 doTheThing。

        如果 obj 可能属于您无法控制的类,请使用类别将您的 doTheThing 方法添加到它们。如果您需要默认行为,请在 NSObject 上添加一个类别。

        在我看来,这是一个更简洁的解决方案,它有助于将逻辑(您正在做什么)与实现细节(如何针对特定不同类型的对象进行操作)分开。

        【讨论】:

        • 在类别中实现方法只是为了避免使用自省工具对我来说听起来更糟。 iE NSJSONSerialization 的JSONObjectWithData:options:error: 可能返回不同的类型。 (数组,字典)。将字典方法破解成数组,反之亦然,对我来说听起来非常愚蠢。
        • 如果只有子类需要有方法怎么办?
        • 如果只有一个子类需要一个方法,那么在基类中有一个方法,默认实现什么都不做,子类中有一个重写的方法做某事。
        • 关于序列化注释 - 是的,您总能找到一个适合 isKindOfClass 的示例,可能就是其中之一。但是,如果您自己控制类,那么使用多态来构建代码几乎总是会更好。一系列 if/else 语句检查接收者的类实际上并不比使用带有 'type' 字段的 c 结构更好。
        • 一般而言,您可以使用基类或协议来定义您要调用的接口——您只需要在极少数情况下使用类别即可将行为应用于您无法控制的类(例如系统类)。
        猜你喜欢
        • 2018-08-11
        • 1970-01-01
        • 1970-01-01
        • 2015-10-29
        • 2013-04-12
        • 2012-09-07
        • 2015-07-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多