Objective-c的新功能。当我用强类型OO语言编写代码时,我喜欢在代码中使我的设计尽可能明确,我也想确保通过检查参数值范围等来维护程序的正确性(例如,在方法的开头确保对象引用不为null,尽可能使用常量..)。这些简单的检查帮助我和我的同事在开发时间内发现问题。
现在在objective-c中工作,我真的很想检查以确保在向协议实现发送消息之前支持选择器。或者手动检查NSArray
中对象的类型兼容性。
这些类型的检查在objective-c程序中是否正常?你什么时候认为这些检查是必要的?
提前致谢。
答案 0 :(得分:2)
你想要做的事情是完全可以接受的,虽然不一定是每个程序员方法的面包和黄油。 (我并不总是这样做,虽然也许我应该这样做。)
你检查的方式是这样的:
if([someObject respondsToSelector:@selector(someSelector)]){
[someObject someSelector];
}
如果向没有响应的对象发送消息,则会导致运行时崩溃。如果您提前检查,您的逻辑可能完全关闭。 (一个常见的例子是当你认为你正在处理一个对象时,当你实际上处理完全不同的东西时。这引入了开发期间崩溃与运行时预期值/行为之间的权衡。
如果你仔细编码,你会比详细检查更进一步。
修改强>
再考虑一下你的问题,运行时还提供了conformsToProtocol:
方法,它允许你检查类或实例是否符合协议。这似乎正是你想要的。
这对于不崩溃实际上至关重要的地方,无论您多么小心,都是在添加对新iOS功能的支持的同时保持向后兼容性。 (在这种情况下,您对新框架的链接很弱,并使用这些相同的检查来确保兼容性。
正如其他人所说,在协议方面,您确实可以获得某种形式的编译时检查。如果某个方法未表示为@optional
,则Xcode会警告您实现不完整。
答案 1 :(得分:1)
如果协议定义将方法声明为@required
,则检查将是多余的,如果@optional
检查它是必须的。如果你想要一个防弹代码(但是,它可能有一些性能上的缺点),检查对象在数组中的类型可能是一种很好的做法,但我自己从来没有这样做过,虽然我通常单独工作,而是比检查类型更具说明性地命名我的数组。 / p>
答案 2 :(得分:1)
关于协议,如果您将方法声明为@optional
,则实现是可选的,因此您应该检查对象是否实际响应选择器(通常您会缓存检查结果而不是每次都检查它)调用)。如果它不是可选的,请不要测试。编译器将为未实现的选择器发出警告,因此如果你想要做的就是失败,那么运行时检查确实不是必需的(运行时将抛出异常并且调试器会中断,所以你会知道缺少什么)
关于检查数组中的对象,您可以这样做,但通常如果您不想接受每个对象,则不会导出数组本身,而是导出addMyObject:(AllowedObject *)object
之类的方法。显然,如果你接受一个数组作为参数并且想要确保它内部的所有对象都符合,你应该检查对象(当你遍历数组时,或者通过调用它上面的indexesOfObjectsPassingTest:
之类的东西检查返回的NSIndexSet
是否与数组具有相同的计数(或者你可以只取NSIndexSet
并从原始数组中获取它描述的子数组然后使用它,这取决于你需要)。
但是,由于Objective-Cs运行时,您不一定要检查每个方法调用。如果它不受支持,调试器将会中断,您可以确定错误。然而,通过NSAssert
宏检查参数的有效性是一个很好的做法(如果您还没有这样做,则编写单元测试,它们也会在一定程度上为您节省很多麻烦!)。