2

我是一名普通的 iOS 开发人员。我看到的第一个被大量使用的设计模式是委托模式,它主要用于回调功能。

现在Objective C中有块,我看到越来越多的库大量使用它们并避免委托,我想知道,块是否永久替代使用协议的委托模式?

我最近在一个项目中使用了 MKNetworkKit,我在它之上创建了一个包装类,该库是基于块的,所以我所有的代码都会封装对其中一个基于块的代码的调用,而不是另一个基于块的代码。

我发现一开始很方便,但是由于代码看起来很复杂,很难调试和修改(callback inside callback inside!)

关于何时使用什么和某些最佳实践的任何提示?

4

2 回答 2

4

委托和块都用于“回调”结果的东西,通常是创建它的东西。有一些区别:

  • 使用委托协议,您必须实现以接收回调的方法名称是固定的。这意味着,如果您需要使用相同的委托协议从多个可能的操作接收回调,您必须以某种方式区分它们。使用块,没有固定的名称;您只需传递具有特定签名的块对象。您可以将不同的块对象传递给不同的操作。
  • 委托协议通常(但不总是)包含多个回调方法,例如“成功”和“失败”回调。每个块只能作为一个回调。许多库尝试通过使用多个参数将多个委托回调“组合”成单个块回调,例如,块有两个参数(结果,错误),如果“错误”为 nil,则它对应于原始的“成功”回调, “结果”是数据;如果 "error" 不是 nil,它对应于原始的 "failure" 回调。另一种选择是为动作单独提供多个块(例如,它具有“成功块”属性和“失败块”属性,您可以设置它们)。这个比较笼统
  • 内存管理:委托通常是弱引用的,因为委托通常是拥有委托人的“父”对象。但是,块是强烈引用的,因为块是一次性的东西,一旦传递给委托人就不再需要了。但是,如果你仔细想想,它并没有真正的不同。对于委托,委托方法通常会对自身(父对象)执行一些操作。对于块,为了做到这一点,块需要对“父”的引用。然后这个引用需要是一个弱引用,以模拟委托模式的内存管理。使用块,父对象代码可以更好地控制委托将如何引用它,因为它设置了块。

总之,可以将任何使用委托协议的 API 系统地转换为使用块的 API,正如我在上面描述的那样——对于每个委托方法,在委托者上添加一个块属性。

于 2012-12-08T10:58:35.920 回答
0

协议和它们与之交谈的指定委托对象与基于块的代码完全不同,后者通常用于封装任务和/或将其运送到 GCD。

我确实在 Apple 的 Block 文档中看到一个地方似乎与代表提供的某些功能相匹配:

块作为回调特别有用,因为块包含要在回调中执行的代码和执行期间所需的数据。

于 2012-12-08T05:53:43.657 回答