ここにはいくつかの問題があります。プロトコルとクラスについて誤解があり、また、善意ではあるが実際には必要以上に生活を困難にしているプロトコルと連携するアプリケーションも持っています。
あなたが対処している最初の問題は、プロトコルとクラスの違い、およびプロトコルの採用とクラスからの継承の違いを理解するためのいくつかの問題です。これは簡単なことではありません。基本的に、プロトコルはオブジェクトへの単なるインターフェースであり、クラスはインターフェースと実装の両方を提供します。つまり、プロトコルは呼び出すことができるメソッドの単なるリストであり、クラスはメソッドのリストであり、それらのメソッドを実行するためのコードでもあります。より完全な説明を得るには、ソースに直接アクセスする方がよいでしょう。おそらく、Apple の「The Objective-C Programming Language」が役に立ちます。そこで、クラスとプロトコルについて読んでください。そうすれば、なぜあなたがそれをするのかわかると思います」id<SetSectionController>
navigationController
プロパティを明示的に定義せずに。ただし、後でこれについて具体的な質問がある場合はお知らせください。
修正が難しい問題は、このSetSectionController
プロトコルです。いくつかの問題があり、それらすべてを説明することは、この回答の範囲外です。これが問題です。実装には、基本的に、このプロトコルを実装するオブジェクトが、どのナビゲーション コントローラーがテーブル ビューに関連付けられているかを知る必要があります。これはこれまで、アプリケーションのデリゲートに結合することでdeus ex machinaを提供してきましたが、この結合を削除するのは正しいことです。しかし、適切なデータをビュー コントローラーに入力してナビゲーション スタックにプッシュする別の方法を見つける必要があります。
プッシュ ロジックをビュー コントローラーに移動する必要があると思います。今のところ、セクション コントローラーは、ビュー コントローラーに必要な情報を提供するインターフェイスを提供します。したがって、セクション コントローラに次の疑似コードのような実装があるとします。
- (void)...didSelectRow...
{
id detailsForIndexPath = self.dataForRows[indexPath.row];
DetailViewController *vc = [DetailViewController new];
vc.details = detailsForIndexPath;
[APPDELEGATE.navigationController push:vc];
}
SetSectionController
次に、 のように呼び出されるメソッドを追加します-dataForRow:
。その実装は、上記のメソッドの最初の行のようになります。次に、View Controller で次の...didSelectRow...
ように実装します。
- (void)...didSelectRow...
{
id<SetSectionController> sc = self.sectionControllers[indexPath.section];
id details = [sc dataForRow:indexPath.row];
DetailViewController *vc = [DetailViewController new];
vc.details = details;
[self.navigationController push:vc];
}
セクション コントローラーが他の有用な処理を行っている場合は、...didSelectRow...
それをビュー コントローラーに移動するか...didSelectRow...
、セクション コントローラーに移動してください。
ポリモーフィズムによって複雑なテーブル セクションを管理しやすくしようとする試みには感謝していますが、このプロトコルは適切な方法ではありませんでした。それは、単一のテーブルの単一のセクションに対して責任のある何かを尋ねる正しい質問であるかどうかを考慮せずUITableViewDelegate
に、やみくもにメソッドをコピーします。UITableViewDataSource
それでも使いたいのであれば、実際にあなたの生活を困難ではなく楽にする形にするには、かなりのリファクタリングが必要になると思います. セクションごとの論理偏差の複雑さによっては、完全に破棄することもできます。しかし、それはまったく別の質問です。お役に立てれば!