【问题标题】:When should data source and delegate be different objects?什么时候数据源和委托应该是不同的对象?
【发布时间】:2014-08-21 03:59:50
【问题描述】:

在什么情况下数据源和委托需要有不同的对象?我遇到的大多数应用程序都强调有self.currentView.delegate = self。它仅仅是为了可读性和分割代码吗?

【问题讨论】:

  • 从来没有必要。

标签: ios cocoa-touch delegates


【解决方案1】:

数据源只是一种具有不同名称和不同职责的委托。文档中的 Apple explains this nicely

数据源就像一个委托,除了,而不是 用户界面的委托控制,它是对用户界面的委托控制 数据。

分离两个角色允许开发人员在适合他们时为每个角色指定不同的对象,而不是强迫他们为两个相关但不同的任务使用单个对象。为这两个角色使用不同的对象从来都不是必要,但有时会很方便。

考虑一个包含一个表格的视图控制器,该表格可以在多个“模式”之间切换,其中每个模式显示具有不同细节的相同项目。实现这样一个表的一种方法是在视图控制器中做所有事情,但你最终会得到如下代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *theCell = nil;
    switch (self.selectedMode) {
        case kFirstMode: {
            // set up the kind of cell required for mode 1
            break;
        }
        case kSecondMode: {
            // set up the kind of cell required for mode 2
            break;
        }
        //...and so on...
    }
    return theCell;
}

你已经闻到负面代码审查的味道了,对吧?

另一种可以说是更好的方法是为每种模式创建单独的数据源对象。当用户切换模式时,您只需换入一个知道如何显示所选模式的数据的新数据源。当不同的模式显示完全不同的数据项而不是相同项的不同方面时,这种方案效果更好。

【讨论】:

  • 感谢您的评论。上面的问题并不是我想要的,但你回答了我真正想知道的问题——我有一个表格视图,可以在两个不同的列表之间切换,我想知道如何最好地管理它。 :-)
【解决方案2】:

指向自我(作为“视图控制器”)当然很受欢迎,我相信这是因为在一个地方编写所有代码“更容易”。

如果您遵循任何架构设计模式,大多数人都会希望您创建具有单一职责的对象。这意味着你的班级只负责一件事,而且只负责一件事。

您可以在此处阅读有关此模式的更多信息: http://en.wikipedia.org/wiki/Single_responsibility_principle

将其付诸实践,您将拥有一个仅负责视图布局的视图控制器和一个仅负责加载数据的附加数据源类。

遵循这些设计模式通常意味着您的代码更整洁、更易于维护,cyclomatic complexity 更少。

符合任何类型的“数据源”协议(委托)的类也是可重用的。这意味着您可以跨多个视图控制器使用相同的数据逻辑,而无需重复代码。

【讨论】:

  • Apple 非常强调 MVC 模式(包括数据源和委托),这就是他们的 API 采用这种方式设计的原因。不是因为“单一职责原则”。 (来源:developer.apple.com/library/ios/documentation/General/…
  • MVC 和单一职责是非常兼容的软件思考方式。事实上,MVC 的一半目的是确保视图层的东西不会承担太多责任。
  • @theMonster 您现在已经两次链接到 MVC 页面来证明您的推理是正确的。也许你应该再读一遍。它只使用了两次delegate这个词(其中一个作为动词),并且只使用了一次data source,但在不同的上下文中。
  • @pixelchild 我认为如果您在第一行使用“视图控制器”代替“自我”,这将是一个更强有力的答案。每个对象都有一个self,重要的是要清楚你在说什么对象。
  • @theMonster 不要那么自卫。我们只是想帮助教育你。也许您可以向我们详细解释一下委托是如何与 MVC 模式“紧密”耦合的。我认为练习本身将有助于你发现你想说什么。
【解决方案3】:

我认为您可能不了解数据源和委托。

您的数据源只是您希望项目使用的数据,即 UIITableView、UICollectionView、UIPicker 等。

上面提到的这些元素具有您可以响应的委托。大多数时候,数据源和委托的代码存在于您的实现文件中,通常是某种 UIViewController 实现。

您可以创建另一个对象来处理控件的委托,但我的意见是在大多数情况下只是添加另一个不需要的层。

希望对你有帮助。

【讨论】:

  • 那么 - 在一个大型项目中,我的数据“模型”会是数据源吗?在情节提要中,我只需要为我的新类创建一个引用出口?
  • 您的故事板是一个视图控制器,您创建一个继承自 UIViewController 或 UITableViewController 的类。您的自定义类充当您的 ui 元素的委托/数据源。您的视图控制器可以从其他来源(核心数据、REST、文本文件等)获取数据。听起来阅读一本书也有帮助。我推荐 Big Nerd Ranch 关于 iOS 的书。这会有很大帮助。
【解决方案4】:

委托:将对象的职责委托给另一个对象。 例如:我们在 UITableView、UITextField 和 UITextView 中使用了委托,这样它就可以告知特定事件的更改和更新。

数据源:数据源的职责是在请求时向另一个对象提供数据。 例如:数据源模式与表视图和集合视图一起使用。告诉他们要显示的行数和单元格数。

【讨论】:

    【解决方案5】:

    根据文档:

    协调控制器提供以下服务:

    • 响应委派消息和观察通知
    • 响应操作消息
    • 管理拥有对象的生命周期(例如,在适当的时间释放它们)...

    但是,重要的是要认识到,在特定情况下,您可以打破这种模式。但目的应该证明手段是正当的。那么什么时候需要呢?每当您作为程序员认为它比将所有回调集中在一个地方更干净时。

    来源:Apple DocsWiki - MVC

    【讨论】:

    • 我不相信 MVC 模式与委托有任何关系。不要误会我的意思,我喜欢 MVC 模式,但除非我弄错了。委托只是指向符合协议的对象的指针(它们是业务逻辑契约)。您可以非常轻松地创建 MVC 视图,而无需单个委托。
    • @pixelchild 如果您阅读:developer.apple.com/library/ios/documentation/General/…,那么您会看到委托非常紧密地集成到 MVC 模式中,这也是它在语言中的重要原因。我已编辑我的帖子以包含此链接。
    • @theMonster 语言是什么? MVC 还是委托?都没有内置到 Objective-C 中。它们都是库的构造,而不是语言。
    • @theMonster 我认为您对“合同编程”(en.wikipedia.org/wiki/Design_by_contract)和 MVC 模式之间的区别有点困惑。没关系,因为它可能非常令人困惑。 Apple 在 Cocoa API 中大量使用委托/协议,是的,它们应该作为其良好的编程实践。然而,我提到的委托本身只是符合契约的对象,与 MVC 模式无关。
    • @theMonster 是的,语言中内置了协议。但是您的第一条评论(我正在回复的评论)没有提及协议。委托和 MVC 都是可以用许多不同的编程语言实现的设计模式。碰巧的是,在 Objective-C 中,委托通常是使用协议来实现的。但这并不意味着委托就在语言中。
    猜你喜欢
    • 2016-04-19
    • 2014-04-06
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 2015-08-08
    • 2011-01-14
    • 2011-06-09
    相关资源
    最近更新 更多