【问题标题】:Objective-C Cocoa Touch: Delegates - I almost get it. Last stepsObjective-C Cocoa Touch:代表 - 我几乎明白了。最后的步骤
【发布时间】:2012-03-25 21:29:46
【问题描述】:

好的,我几乎明白了。我在 Objective-c 中做了很多阅读,我真的很想了解委托,因为它对于 cocoa-touch 似乎非常重要,我想设计一个 iPhone 应用程序。

因此,委托是可以被赋予特定任务的对象。如果它实现某些功能,则据说它遵循“协议”。例如,一个视图控制器可以说“嘿,我不确定从哪里获取这些数据......或者嘿,我不知道如何格式化这个东西......你能为我做吗? "并且代表就像“确定我得到了你的保障”。

好吧,这对我来说很有意义。对我来说没有意义的是我如何让委托将内容返回给视图控制器。比如说我的代表可以访问一个 URL 并阅读体育比分或其他内容。所以我说“委托给我这个分数”......我如何让视图控制器说“明白了,在这里”,然后将它放在视图控制器中。我的理解可能在这里存在差距。我是否必须在委托中实例化视图控制器?这对我来说没有意义......因为那样我就有两个视图控制器......如果你能说得更清楚,请随意改变我的类比。

谢谢!

【问题讨论】:

    标签: objective-c xcode cocoa-touch delegates


    【解决方案1】:

    我认为您感到困惑,因为类似的模式用于(但不限于!)两个常见任务,这两个任务都适用于您的情况。

    模式

    • 让外部对象为您提供数据(这通常称为数据源)。例如,参见UITableViewDataSource 协议。

      这是通过方法的返回值实现的:例如

      - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
      实现协议的对象向调用者返回一些值(在本例中为一个单元格)。

      关于数据源我会提到:数据源本身(实现协议的对象)通常包含更多应用程序的自定义逻辑,而需要数据的控制器source 可以更通用。例如,UITableView 是一个显示表格视图的通用视图控制器,而实​​现 UITableViewDataSource 协议的类需要了解应用程序数据库的详细信息。

      (但是,为了彻底,您通常会为自定义逻辑子类化 UITableView,但这通常是表示逻辑而不是业务逻辑。)

      这些方法调用您的应用程序逻辑,并应立即返回

    • 完成加载数据后提供回调。

      例如,NSURLConnection 类具有对应的NSURLConnectionDelegate 协议。最常见的使用模式是:

      1. 您的对象创建了一个 NSURLConnection,它自己作为委托
      2. 您配置并启动连接。
      3. 您通过您实现的委托方法接收进度和数据。

      在这种情况下,需要委托的对象是一个辅助对象,它知道如何在后台从 URL 加载数据。委托方法是对您的应用程序逻辑的回调,并且在对象被告知开始加载数据(或它的设计目的)之后随时被调用。 p>

    • Delegation 还用于 iOS 上的其他事情,例如由符合 UITableViewDelegate 的对象执行的 UI 相关任务。

    你的情况

    这一切都取决于你的应用程序是什么,以及你的视图控制器负责什么——但听起来你希望视图控制器委托数据加载——基本上,它需要一个数据源。 (您还应该考虑内置的 UITableView 和 UITableViewDataSource 是否适合您的需求。)但是如果您的数据源要从互联网异步加载数据,则可能需要实现一些数据加载回调 通过诸如 NSURLConnection 之类的东西。

    这两种方法不一定配合得很好,因为视图控制器会期望其数据源立即返回数据,但数据源可能需要等待数据加载。

    这就是为什么 UITableView 有一个方法-reloadData,所以作为数据源的对象可以在数据可用时告诉它。您可能希望在您的应用程序中使用这样的模式。

    (但同样,您很可能不需要实现完全自定义的堆栈——您可以组合一些类来减少对委托的使用,或者您可以使用更多的内置类来满足您的需求。)

    【讨论】:

    • 虽然我认为你是对的,他在这些方面感到困惑,但我认为你的细分不太准确。有很多同步委托协议。例如,UITableViewDelegate 与 UITableViewDataSource 是分开的,但它遵循的模式更像是您在这里所说的“数据源”(因为您似乎要绘制的主要区别是同步与异步)。
    • 是的,我在写答案时意识到了这个问题。最初我打算将所有内容分为两类,但现在我不认为它们是唯一的类别。我会尝试编辑以澄清。
    • 嗯。好的。所以在我的实际情况中(我应该在 OP 中提到这一点,我不确定我为什么不这样做)我有一堆对 facebook API 的调用。这些是异步的,并且有多个请求必须出去然后回来..然后我不想组合来自回调的所有数据并将它们推到 TableView 中。什么是正确的模式?似乎我应该有一个 FacebookAPIDelegate 类,而不是发送和接收请求,但是我如何将该数据返回给视图控制器..或表视图控制器?还是我离基地太远了。非常感谢!
    • 在这种情况下,我可能会从您的 UITableViewController 子类调用 Facebook API。只需更新内存中的数据并调用-reloadData,以便新记录显示在表格视图中(一旦数据加载完成)。
    【解决方案2】:

    使用返回值定义协议的方法。

    也就是说,获取 URL 是一个不好的例子,因为等待委托返回结果会阻塞调用线程。在这种情况下,您必须有一种方法让委托在完成后回调结果。这可以通过将委托传递给委托,或者将一个或多个 Objective-C 块传递给委托(onSuccess、onError 等)来实现。

    在这个问题上,块比委托和协议更容易编码,并且正在逐渐在 Apple 和第三方 API 中取代它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-24
      • 2012-02-07
      相关资源
      最近更新 更多