1

新的objective-c。当我用强类型的 OO 语言编写代码时,我喜欢让我的设计在代码中尽可能明确,我还喜欢通过检查参数值范围等来确保我保持程序的正确性(例如,在方法的开头确保对象引用不为空,尽可能使用常量..)。这些简单的检查帮助我和我的同事在开发期间发现问题。

现在在 Objective-c 中工作,我真的很想在向协议实现发送消息之前检查以确保支持选择器。或者手动检查NSArray.

这些类型的检查在 Objective-C 程序中是否正常?您认为何时需要进行这些检查?

提前致谢。

4

3 回答 3

2

您尝试做的事情是完全可以接受的,尽管不一定是每个程序员方法的基础。(我并不总是这样做,尽管也许我应该这样做。)

你检查的方式是这样的:

if([someObject respondsToSelector:@selector(someSelector)]){
  [someObject someSelector];
}

如果您向对象发送消息但它没有响应,您将遇到运行时崩溃。如果您提前检查,您的逻辑可能完全不正确。(一个常见的例子是当你认为你在处理一个对象时,实际上你在处理完全不同的东西。这引入了开发过程中的崩溃与运行时的预期值/行为之间的权衡。

如果您仔细编码,您将比详细检查走得更远。

编辑:

再考虑一下您的问题,运行时还提供了该conformsToProtocol:方法,该方法允许您检查类或实例是否符合协议。这似乎正是您想要的。

无论您多么小心,这对于不崩溃实际上至关重要的地方是,当您添加对新 iOS 功能的支持同时保持向后兼容性时。(在这种情况下,您对新框架的链接较弱,并使用这些相同的检查来确保兼容性。  

正如其他人所指出的,当涉及到协议时,您确实会得到某种形式的编译时检查。如果一个方法没有被标记为@optional,Xcode 会警告你一个不完整的实现。

于 2012-12-13T03:25:04.503 回答
1

如果协议定义将方法声明为@required检查将是多余的,如果它正在@optional检查它是必须的。如果您想要一个防弹代码,检查数组中对象的类型可能是一个好习惯(但是,它可能有一些性能缺陷),但我自己从来没有这样做过,尽管我通常独自工作并且宁愿以暗示性的方式命名我的数组而不是检查类型。

于 2012-12-13T03:24:28.373 回答
1

关于协议,如果您将方法声明为@optional,则实现是可选的,因此您应该检查对象是否实际响应选择器(通常您缓存检查的结果,而不是在每次调用时检查它)。如果它不是可选的,请不要测试。编译器将对未实现的选择器发出警告,因此如果您只想失败,则实际上不需要运行时检查(运行时将抛出异常并且调试器将中断,因此您无论如何都会知道缺少什么) .

关于检查数组中的对象,您可以这样做,但通常如果您不想接受每个对象,您不会导出数组本身,而是导出类似addMyObject:(AllowedObject *)object. 显然,如果您接受一个数组作为参数并希望确保其中的所有对象都符合,您应该检查该对象(当您遍历数组时,或者通过调用类似indexesOfObjectsPassingTest:的东西并检查返回的NSIndexSet是否有与数组相同的计数(或者您可以NSIndexSet从原始数组中获取并获取它所描述的子数组,然后使用它),具体取决于您的需要)。

但是,由于 Objective-C 运行时,您不必检查每个方法调用。如果不支持,调试器将中断,您可以确定问题所在。然而,通过宏检查您的参数或有效性是一个好习惯NSAssert(如果您还没有这样做,请编写单元测试,它们也会在某一时刻为您省去很多麻烦!)。

于 2012-12-13T03:25:39.137 回答