目标C:块与select器与协议

我经常发现自己写了“实用”类,可以在我的项目中重复使用。

例如,假设我有一个“地址簿”视图。 我可能想要使用我的地址簿来select发送电子邮件的人员,或者将其添加到会议请求中的人员。

我开发了这个视图控制器,以便电子邮件控制器和会议控制器可以使用某种callback机制来让调用者知道用户是否从地址簿中select了某个人,或者他们被取消了。

在这种情况下,似乎基本上有四种(合理的)方法。

  • 在AddressBookController上创build一个“AddressBookDelegate”协议和相应的委托属性。 然后使用协议中定义的消息来传递结果(类似于UIActionSheetDelegate)。

  • 在AddressBookController上创build一个“非正式”的“AddressBookDelegate”协议和一个相应的委托属性,但委托属性的types将是“id”,并在运行时检查“respondsToSelector:”,看看委托是否实现了我们的方法需要(似乎大部分框架的东西已经开始这样)。

  • 向AddressBookController传递一个表示委托的id,以及两个SEL,它们指定在用户select用户或取消请求时调用的方法。 我看到的好处是, 假设一个控制器支持发送电子邮件和build立会议(在这个例子中,我知道这似乎是不好的devise…但是可以想象一个更一般的情况,这对于公用事业类似乎是完全合理的) – 在这种情况下,你可以传递AddressBookController的不同SEL,具体取决于你是将用户添加到电子邮件中,还是将用户添加到会议中……这是对iVar的巨大改进,用于表示控制器的“状态”。

  • 通过AddressBookController两个块; 一个在用户从地址簿中select一个人时运行,另一个在用户取消请求时运行。

这些积木对我来说非常有用,而且更加优雅,我发现自己几乎不知道什么时候不使用它们。

我希望更有经验的StackOverflow社区的成员比我可以帮助他们对这个主题的想法。

“传统”的方式是通过一个协议。 在@protocol被添加到语言之前使用了非正式语言,但那是在我的时间之前,至less在过去的几年里,非正式的协议已经被泄露,特别是@optional说明​​符。 至于通过两个SEL的“委托”,这看起来比宣布一个正式的协议还要丑陋,而且对我来说似乎也不正常。 块是非常新的(尤其是在iOS上),就像这些事情一样,虽然我们还没有看到大量的文档/博客上最好的尝试和真正的风格,我喜欢这个想法,这似乎是事情块是最好的:整洁的新的控制stream程结构。

基本上我想说的是,这些方法中的每一个都是随着年龄而变化的,除了风格之外,没有一个比上一个更好,这显然是非常重要的,并且最终是为什么这些东西都是被创造出来的。 基本上,你可以select你感觉最舒服的东西,这应该是封闭的或是正式的协议,而你的困惑很可能来自冲突的源头,因为它们是在不同的时间写的,但是从时间的angular度来看,它是清楚看哪个取代别人。

[Controller askForSelection:^(id selection){ //blah blah blah } canceled:^{ //blah blah blah }]; 

可能比定义两个额外的方法,以及为它们(forms上或是其他方面)的协议,或者通过SEL并将它们存储在ivars等等中更加简洁。

我会只用你的第一个方法。 这是Cocoa尝试过的真实模式,看起来非常适合你正在做的事情。

对其他方法的一些评论:

  1. 非正式的协议 – 我真的没有看到在正式协议上做这件事的好处。 每一个自从正式协议获得了@optional方法以后,非正式协议的效用就less得多了。
  2. 传递SELs – 我不认为这是cocoa的一个既定模式。 我个人并不认为它比代表方式更好,但如果它更适合你的想法,那就去做吧。 你并没有真正摆脱状态; 你正在转变成别的东西。 就个人而言,我宁愿有一个伊娃,我可以设置和检查,而不必使用select器types。
  3. 传球 – 这是一种新时代的方式,它有一些优点。 我觉得你应该小心,因为在我看来,它并不能很好地扩展。 例如,如果NSTableView的委托和数据源方法都是块,我个人觉得有点烦人。 想象一下,如果你想设置10个不同的块,你的-awakeFromNib (或其他)方法将是相当大的。 在这种情况下,单个方法似乎更合适。 但是,如果你确信你永远不会超越两种方法,那么块方法似乎更合理。