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

Ios 当已知某个对象符合协议时,断言该对象包含某些方法是一种好模式吗?,ios,objective-c,design-patterns,Ios,Objective C,Design Patterns,出于项目UI的目的,我正在UIViewController上的类别中创建一个常规方法,用于设置导航项的UI。此特定导航项有一个对应于操作(保存、确定、选择等)的黄色按钮和一个灰色按钮(取消、关闭) 我想我可以把这个方法做得更小,就像这样: - (void)configureAsSaveCancelIPadHeaderWithTarget:(id<PSaveCancelViewControllerNavigationBar>)theTarget 我以后肯定会调用这两个方法(save、

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

我想我可以把这个方法做得更小,就像这样:

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

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

这一切都取决于您希望使事情变得多么“安全”。仅仅因为您的参数指定需要协议,实际上并不意味着传递的实例实现了该协议。编译器所需要的只是让您保证在调用(强制转换)时它会这样做

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


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

这完全取决于你想让事情变得多么“安全”。仅仅因为您的参数指定需要协议,实际上并不意味着传递的实例实现了该协议。编译器所需要的只是让您保证在调用(强制转换)时它会这样做

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


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

不,这是毫无意义的,而且非常冗长。您已经声明了in-configureAsSaveCancelIPadHeaderWithTarget:您只接受一个实现协议的对象,因此您将真正努力使自己骨瘦如柴,这将起作用

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


代码越少越好。

不,它毫无意义,而且非常冗长。您已经声明了in-configureAsSaveCancelIPadHeaderWithTarget:您只接受一个实现协议的对象,因此您将真正努力使自己骨瘦如柴,这将起作用

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


代码越少越好。

我不认为这是一个“模式”问题。这实际上取决于你希望有多强的防御能力,以及这些方法缺失的可能性有多大。通常,在调用委托方法时,在调用它之前先检查它是否存在。@trojanfoe是的,谢谢。在本例中,我将选择器分配给UIButton,因此在单击按钮之前没有机会检查选择器是否存在。如果按下按钮时该选择器不存在,应用程序将崩溃。在这种情况下,我认为您使用断言的方法是正确的,无论这些方法的
@required
属性如何。我不认为这是一个“模式”问题。这实际上取决于你希望有多强的防御能力,以及这些方法缺失的可能性有多大。通常,在调用委托方法时,在调用它之前先检查它是否存在。@trojanfoe是的,谢谢。在本例中,我将选择器分配给UIButton,因此在单击按钮之前没有机会检查选择器是否存在。如果按下按钮时该选择器不存在,则应用程序将崩溃。在这种情况下,我认为您使用断言的方法是正确的,无论这些方法的
@required
属性如何。如果您自己进行这些检查,您可能会失败,并显示更好的错误消息<代码>MBMethodNotImplementedException:实例0x42未实现“-bar:”协议中指定的“比
-[Foo bar:]更容易理解:未识别的选择器发送到实例0xirgendwas
@MatthiasBauch,因此您是说触发名为……的NSException exception exception是一个更好的主意,而不是断言?使用断言可以指定异常消息,这只是抛出异常的另一种方式。关键是要创建一条有意义的消息。如果你自己做这些检查,你可能会失败,产生更好的错误消息<代码>MBMethodNotImplementedException:实例0x42未实现“-bar:”协议中指定的“比
-[Foo bar:]更容易理解:未识别的选择器发送到实例0xirgendwas
@MatthiasBauch,因此您是说触发名为……的NSException exception exception是一个更好的主意,而不是断言?使用断言可以指定异常消息,这只是抛出异常的另一种方式。关键是要创造一个有意义的信息。
- (void)configureAsSaveCancelIPadHeaderWithTarget:(id<PSaveCancelViewControllerNavigationBar>)theTarget
@protocol PSaveCancelViewControllerNavigationBar <NSObject>
@required
- (void)save:(id)sender;
- (void)closeThisView:(id)sender;
@end
    - (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.");