Ios4 代码块是否完全替换委托?

Ios4 代码块是否完全替换委托?,ios4,delegates,Ios4,Delegates,既然iphone/ipad开发最终支持了块,那么这些是否完全消除了对委托的需求,或者委托作为一个完整的接口实现是否仍然更干净,而块更适合于单个任务?有趣的想法-虽然您可以使用块/闭包代替回调方法,我不知道如何用它来取代委托系统——毕竟,委托几乎是一种对象到对象通信的方式,因此其可能性比简单地执行任意代码要丰富得多 因此,我不得不同意你的“更适合单个任务”的评论(甚至只是某些单独的任务)。我一直在寻找关于这方面的官方文件,但还没有找到任何。基于对iOS 5中公开的新类和对现有类的添加的回顾,我建议

既然iphone/ipad开发最终支持了块,那么这些是否完全消除了对委托的需求,或者委托作为一个完整的接口实现是否仍然更干净,而块更适合于单个任务?

有趣的想法-虽然您可以使用块/闭包代替回调方法,我不知道如何用它来取代委托系统——毕竟,委托几乎是一种对象到对象通信的方式,因此其可能性比简单地执行任意代码要丰富得多


因此,我不得不同意你的“更适合单个任务”的评论(甚至只是某些单独的任务)。

我一直在寻找关于这方面的官方文件,但还没有找到任何。基于对iOS 5中公开的新类和对现有类的添加的回顾,我建议我的团队假设一个委托协议,但在特定调用和块的性能之间存在直接因果关系时,提供一个块

因此,根据经验,当需要进行持续通信时,代理协议是正确的,导致通信的动作是分散的,或者动作来自第三个来源。块主要与异步操作关联,特别是与单次类关联

编辑:下面是一些例子:

UIScrollViewDelegate
是一个正确的委托协议,因为(i)可能需要沟通的事情很多;(ii)可能需要在任何时间以任何顺序传达;以及(iii)由于代表无法控制的原因进行沟通


NSURLConnection+sendsynchronousrequest:queue:completionHandler:
正确地使用块传递结果,因为(i)只有一个结果要报告;(ii)该报告是来电者采取行动的直接结果。

我正试图决定是对其他答案发表评论,还是留下自己的答案。我决定了,就在这里

我主要是一名C#开发人员,因此我可以很容易地看到如何用块替换整个委托模式,因为C#始终将动词视为一等公民。事实上,当我开始使用Java和Android平台时,这是最难适应的事情之一。当我学习Objective-C和Cocoa时,这种经历让我变得更容易

我认为这是一个观察者模式与委派模式的实现细节,我对此感觉不是特别强烈。我非常注重组合而不是面向继承,因此我经常使用委托模式,即使在C#中也是如此

我认为两者都不应该取代另一个。我认为这两种模式应该在各自最合适的地方使用;然而,我发现在Cocoa中,我肯定更喜欢observer模式而不是delegation模式

例如,我觉得处理UIAlertView的结果应该基于块而不是委托。这对我来说总是有点奇怪,但在开发API的特定部分时,块是不可用的。因此,我永远无法确定苹果是否认为这是首选方法,或者这是当时唯一的方法

最近,我将GameKit集成到我的一个游戏中,发现大多数异步调用(事实上,我使用过的所有调用)都不使用委托;他们使用积木。我想如果他们今天能够重写UIAlertView,他们可能会使用块而不是委托来处理用户输入后的回调。当然,这只是猜测


对您的问题的简短回答是:在组合对象时,我更喜欢委托模式,以避免不必要的复杂继承层次结构;在处理类似于回调和事件处理程序之类的事件时,我更喜欢观察者模式。我用代表来表示前者,用块来表示后者。

我正在做我自己的研究,我发现这篇文章很有启发性,是贾斯汀·德里斯科尔写的,我希望它也能帮助其他人


以下是链接:

委托-当您想了解流程/事件/状态时,可以使用委托。例如,在NSURLConnectionLegate中,您将通过两个或多个委托方法获得数据的状态。didReceive:NSData CONNECTIONIDFINISHLOADING

块-您只能在预期结果或错误时使用块


最佳参考-

简短的答案是。但是你可能不想这样做,因为这是非常多余的

让我们看看委托的一个最常见的用例-CollectionViewDelegate,我们想使用它最流行的方法-collectionView:didSelectItemAtIndexPath

对于委派,我们只需要做一件事:

    @interface MyView () <UICollectionViewDelegate>
    @end

    @implementation MyView {
    ...
    -(void)collectionView:(UICollectionView *)collectionView 
           didSelectItemAtIndexPath:(NSIndexPath *)indexPath {

        // add the implementation here.
    }
考虑CollectionViewDelegate中的许多委托方法,您需要实现您想要涉及的每个方法,代码变得很难阅读

最后,让我们看看Apple对委托和块的定义:

委托是一个对象,当该对象在程序中遇到事件时,它代表另一个对象或与另一个对象协同工作

当一个街区 “Objective-C类定义了将数据与相关行为相结合的对象。”


我们可以安全地得出结论,block和delegate是为不同的目的而设计的,并且擅长于它们所分配的任务。我们应该使用其中一种,这取决于我们想要实现的目标。

如果有任何好的例子,请再解释一下。Thanks@Sandy我主张,街区是一个很好的方式来提供具体行动的结果,但更广泛的谈话的基础。提供一个块就像听众说的
    @implementation MyView {
     ...   
     void (^didSelectItemAt)(NSIndexPath*) = ^(NSIndexPath *indexPath) {
          // do a bunch of things to display the cell
          URLFromCell();
          PaneFromURL();
          self.NavigationController.pushView();
      }         
    }