Objective C中几个不同视图控制器之间通信的正确方法

时间:2013-01-25 20:12:27

标签: ios objective-c casting

我有一个非常简单的应用程序直到今天。它有一个带有3个标签的标签栏视图控制器。中间的标签是一个摄像头,另外两个是桌面视图。标签栏视图控制器是应用程序中所有数据的中心枢纽。所以,从那里,我将表格的数据数组设置为:

(PLEListViewController*)[self.viewControllers objectAtIndex:0] setList:newList];

显然,PLEListViewController是我的UITableView子类。

现在,我想将表视图包装在UINavigationController中,这非常简单。但现在,这行代码转变为:

[(PLEListViewController*)((UINavigationController*)[self.viewControllers objectAtIndex:0]).topViewController setList:newList];

代码中有15行执行此操作,这并不令人愉快。

所以我的问题是:我这样做的更优雅的方法是什么?我不知道?

3 个答案:

答案 0 :(得分:4)

您需要使用您的架构。制定适当的数据源和委派协议,以确保您的类可以匿名进行通信。你现在拥有的是非常不灵活的,随着你的应用程序的增长/变化,它会变得更糟。

答案 1 :(得分:4)

你现在问这个并看到问题是件好事。您的问题可以在您的问题中找到。 “在Objective C中几个不同视图控制器之间进行通信的正确方法”的答案是“不要”。具体来说,你的错误就在这里:

  

标签栏视图控制器是应用程序中所有数据的中心枢纽。

视图控制器永远不应该保存应用程序中的任何数据。您的数据应该存在于您的模型类中。所有视图控制器都应该与模型类通信。他们应该很少互相交谈。这是MVC的核心。

因此,您将“列表”(无论是什么,无关紧要)移动到所有视图控制器都知道的模型对象中。该模型对象可以是单例,或者通常更好,它可以在创建时传递给视图控制器。当事情发生变化时,您可以更改模型。在viewWillAppear:中,您更新视图控制器以匹配模型的当前状态。

当它当前不在屏幕上时,永远不要假设视图控制器存在。如果您的设计需要存在非活动视图控制器,那么您的设计需要修复。

答案 2 :(得分:1)

您希望使事物更加松散耦合,而不是编码代码中对象之间链接的显式遍历。

假设您有一个数据模型显示在应用程序的不同位置,我认为有两种方法可以帮助......

一种方法是使用视图控制器层次结构。例如,使用[ self enclosingTabBarController ]查找最近的父标签栏控制器并获取它的数据模型属性。用-enclosingTabBarController代替适用于您的应用程序的内容。

另一种方法是“数据模型作为单身”方法。为此你可以

  • 将数据移至您的应用代表,并通过((MyApplicationDelegateClass*)[ UIApplication sharedApplication ].delegate).dataModel
  • 进行访问

  • 为您的应用提供单例数据模型对象,并通过[ MyDataModelClass sharedModel ]
  • 进行访问

在任何情况下,您都会转向更松散的耦合,这需要对应用中对象之间的链接进行更少的显式遍历。少即是多了!