2010-11-27 11 views
1

1つのビューコントローラを別のビューコントローラから参照する際に問題があります。コードは機能しますが、警告が表示され、私は間違っていると思います。 controllerNavigationControllerにあるtableViewのデータをリロードしようとしています。ViewController階層を正しくトラバースするには?

AppDelegateから:このようなメッセージと間違って何
これは動作しますがXcodeのはselectedViewControllernavigationControllerを返すことを知らないため

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

は、私は警告request for member 'topViewController' in something not a structure or unionを取得します。だから私は、次の操作を行うことができます: ​​

をしかし、私はこの警告を得る:incompatible Objective-C types initializing 'struct UIViewController *', expected 'struct UINavigationController *'

はどこまで私はこれで行くことがありますか?最初の行が機能します。 「正しい方法」に到達するには、8行のコードが必要ですか?

答えて

4

メジャーコードがここにあります。あなたは(素晴らしい)距離で行動しようとしています。あなたが達成しようとしていることが明確ではないし、なぜあなたがアプリケーションデリゲートからこのアクションを行う必要があるのか​​も分かりません。私は巨大な泥のような大規模な巨大な塊のように、アプリケーションデリゲートを扱う開発者もいると思っています。これは、iOS開発から除外されるべきアンチパターンです。

質問に戻る:タブビューコントローラ内のテーブルビューコントローラに強制的にデータをリロードしようとしています。私はこれが何か起こっていることに反応していると仮定しています。なぜアプリケーションの代理人の代わりに、そのイベントを監視しているテーブルを担当しているビューコントローラを持っていないのですか?そのようにして、テーブルビューを所有するものは直接MVCパターンの全体を制御します。これは、複雑さ、可読性、および脆さの観点から、アプリケーションが階層を介してドリルダウンしてテーブルビューを見つけるようにするよりもはるかに優れたアプローチです。

何らかの理由で、そのビューコントローラがイベントを直接観察することができない場合(その理由がわからない場合)は、いつでもアプリケーションの代理人にNSNotificationを投稿させ、ビューコントローラオブザーバーとしてテーブルレジスタを担当する。直接の観測ほど良くはありませんが、あなたの現在のアプローチよりもはるかに良いです。

+0

私はあなたのポイントを見ます。このアクションを開始しているイベントは、アプリケーションに 'application:handleOpenURL'を介して渡されたファイルです。私が 'tableViewController'の中でメソッドを呼び出すと、このアクションを処理させることになります(これは良い考えです)。 'AppDelegate'から' tableViewController'を一度参照する必要があります。私はこの問題に関連するだけでなく、しばしばこのジレンマに遭遇します。それは私が常にスパイダーのウェブであるポイントに別のプロパティで1つのオブジェクトを格納しているようだ。だからこそ私はコードの最初の行を、それを避けるために試みていました。 – Andrew

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プロパティに外部からアクセスすべきではありません。ビューコントローラ自体にreloadDataメソッドでその動作をカプセル化する必要があります。たとえそれが.tableViewreloadDataと呼んでも、カプセル化する必要があります。これにより、コードがモジュール化され(ユーザーや他の人にとって理解しやすくなります)、View Controllerを拡張してトラックに沿って複雑にするのが簡単になります。

このアプリの構造を正確に知らなければ、通知やオブザーバーを使用してVCにデータをリロードする方が良いでしょう。 UIリフレッシュを必要とするグローバルイベントがある場合は、NSNotificationを使用すると、コードを素早くモジュール化しながらUIレイヤーにメッセージを表示させることができます。

+0

コードが機能しました。私はこれらのメッセージに型キャストをする方法を私は思っていた。私は 'reloadData'の提案と、Shaggy Frogと同様にNotificationsを使用することを検討します。 – Andrew

関連する問題