当知道该对象符合协议时,断言一个对象包含某些方法是一种好的模式吗?

时间:2014-01-09 09:44:40

标签: ios objective-c design-patterns

出于项目UI的目的,我在UIViewController的类别中创建了一个通用方法,用于设置导航项的UI。此特定导航项目有一个黄色按钮对应一个动作(保存,确定,选择等)和一个灰色按钮(取消,关闭)

- (void)configureAsSaveCancelIPadHeaderWithTarget:(id)theTarget actionForYellowButton:(SEL)selYellow actionForGrayButton:(SEL)selGray

我想我可以让这个方法更小:

- (void)configureAsSaveCancelIPadHeaderWithTarget:(id<PSaveCancelViewControllerNavigationBar>)theTarget

让目标响应协议。

协议如下所示:

@protocol PSaveCancelViewControllerNavigationBar <NSObject>
@required
- (void)save:(id)sender;
- (void)closeThisView:(id)sender;
@end

如果未实施这两种方法,@required关键字只会发出警告。

问题

如果目标包含这两种方法,它是否被认为是在configureAsSaveCancelIPadHeaderWithTarget:方法中断言的好模式?像这样:

    - (void)configureAsSaveCancelIPadHeaderWithTarget:(id<PSaveCancelViewControllerNavigationBar>)theTarget 
{
    NSAssert([theTarget respondsToSelector:@selector(save:)], @"The provided target must implement the PSaveCancelViewControllerNavigationBar protocol and have the methods defined in that protocol.");
    NSAssert([theTarget respondsToSelector:@selector(closeThisView:)], @"The provided target must implement the PSaveCancelViewControllerNavigationBar protocol and have the methods defined in that protocol.");

我肯定会在稍后调用这两个方法(save,closeThisView),因此我必须确保调用此方法的类已实现它们。

2 个答案:

答案 0 :(得分:2)

这完全取决于你想做什么'安全'。仅仅因为您的参数指定需要协议并不意味着传递的实例实现该协议。所有编译器都要求你保证在调用(强制转换)时它会这样做。

通常,如果您正在编写所有代码,那么仅使用协议并且不在运行时检查是相对“安全”的。

如果其他人正在使用该代码,特别是如果您将代码作为库或类似的东西发布,则检查变得更加谨慎,因为您无法对其他人将要执行的操作做出任何假设。在这种情况下,提早失败要好得多。

答案 1 :(得分:2)

不,这是毫无意义和冗长的罗嗦。你已经在-configureAsSaveCancelIPadHeaderWithTarget中声明:你只接受一个实现你的协议的对象,所以你真的要自己去做骨头,它会起作用。

你可以无限地“安全”地检查每个对象是否仍然响应他们所说的回复的消息,但所有额外的冗长只会使你的代码难以阅读,难以改变,更慢,并且给你更多机会介绍错误。

更少的代码是更好的代码。