2010-11-27 88 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