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



出于我项目的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.");

肯定会在以后调用这两个方法(保存,关闭ThisView),因此我必须确保调用此方法的类已实现它们。

这完全取决于你想制造东西的"安全"程度。仅仅因为您的参数指定需要协议实际上并不意味着传递的实例实现了该协议。编译器所需要的只是你承诺它在调用(强制转换)时这样做。

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

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

不,这是毫无意义和额外的罗嗦。你已经在 -configureAsSaveCancelIPadHeaderWithTarget 中声明:你只接受一个实现你的协议的对象,所以你要真正努力地把自己骨化,它会起作用。

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

代码越少越好。

最新更新