2010-11-27 94 views
1

我在引用另一个视图控制器时遇到了问题。代码的作品,但我得到警告,这让我觉得我错了。我试图重新加载tableView中的数据,其controller位于NavigationController
有什么不对这样的消息:正确地遍历ViewController层次结构?

从AppDelegate中:

[self.tabBarController.selectedViewController.topViewController.tableView reloadData];

虽然这工作,我得到警告request for member 'topViewController' in something not a structure or union因为Xcode的不知道selectedViewController将返回navigationController。所以,我可以做到以下几点: ​​

但后来我得到这样的警告:incompatible Objective-C types initializing 'struct UIViewController *', expected 'struct UINavigationController *'

我有多远一起去吗?第一行工作。为了达到“正确的方式”,需要8行代码?

回答

4

这里是一个主要的代码气味,IMO。你正试图在一个(很棒的)距离上做出行动。这并不完全清楚你想要完成什么,也不知道为什么你需要从应用程序委托中执行此操作。我曾经看到一些开发者将应用程序委托视为一个巨大的全球性泥巴,我认为这是一种应该从iOS开发中消除的反模式。

回到你的问题:你试图强制一个表视图控制器,在一个选项卡视图控制器,以重新加载其数据。我假设这是为了回应发生的事情。为什么不让视图控制器负责该表,而是监视该事件而不是应用程序委托?这样,拥有表视图的东西直接控制它 - 这是MVC模式的整个点。与复杂性,可读性和脆弱性相比,这是一个好得多的方法,它让应用程序委托向下钻取层次结构以查找表视图。

如果出于某种原因,您不能或不会让该视图控制器直接观察事件(难以理解为什么是非法的),您可以始终让应用程序委托发布NSNotification并让视图控制器作为观察员负责表格登记。不如直接观察,但肯定比你现在的方法更好。

+0

我明白了你的观点。启动此操作的事件是通过`application:handleOpenURL`从另一个应用程序传递给应用程序的文件。如果我决定在我的`tableViewController`中调用一个方法来让它处理这个动作(这听起来像个好主意)。我仍然需要从AppDelegate引用`tableViewController`一次。我经常遇到这种困境,而不仅仅是关于这个问题。看起来我不断将一个对象存储为另一个对象的属性,直到它只是一个蜘蛛网。这就是为什么我在尝试第一行代码,以避免这种情况。 – Andrew 2010-11-27 07:49:36

2

除非编译器知道使用它的是什么类型的对象,并且该对象类型可以接收带有该名称的消息,否则不能使用点符号。

您可以使用点符号与一群类型强制转换的(在这种情况下,是极其丑陋的):

[((UITableViewController *) ((UINavigationController *) self.tabBarController.selectedViewController).topViewController).tableView reloadData]; 

或者你可以把它分解成不连续的步骤:

UINavigationController *navController = (UINavigationController *) self.tabBarController.selectedViewController; 
UITableViewController *tableViewController = (UITableViewController *) navController.topViewController; 
[tableViewController.tableView reloadData]; 

请注意,我假设您的顶级VC是UITableViewController的子类。

您确实不应该在外部访问.tableView属性 - 您应该在View Controller本身上使用reloadData方法封装该行为。即使它的全部内容是reloadData.tableView,也应该封装它。这将使您的代码更加模块化(这会使您和其他人更容易理解),并使您可以更轻松地扩展并增加View Controller的复杂性。

如果不知道这个应用的结构如何,我想你可能会更好地使用通知或观察者来让你的VC重新加载它的数据。如果您有一些需要刷新UI的全局事件,则可以使NSNotification成为UI层获取消息的好方法,同时保持代码的完美和模块化。

+0

太棒了。你的代码工作。我想知道如何才能对这些消息进行类型转换。我会考虑`reloadData`建议,以及可能使用通知作为Shaggy Frog提到的。 – Andrew 2010-11-27 07:57:33