2

次のエラーが表示されます

Property 'navigationController' not found on object of type

私はこのプロジェクトを継承しましたが、何が起こっているのかわかりません。

didSelectRowAtIndexPath の m ファイルには、

[self.navigationController pushViewController:nextController animated:YES];

アウトレットであるアプリ デリゲート ナビゲーション コントローラーにアクセスしていたので、以前は問題ありませんでした。ただし、問題が発生しているため、このアプローチから離れなければなりませんでした。プロジェクトの残りの部分を変換しました。しかし、プロジェクトが通常のテーブル ビューを使用していないこの状況では、ナビゲーション コントローラーは利用できないようです。他の7つのビューでこの問題があります。これを修正して、このよりクリーンなコードを維持できることを願っていますか?

ここに画像の説明を入力 私はこれに本当に戸惑っています.SetsStyleSectionControllerはView ControllerではなくNSObjectであるため、これが発生していると思います.

ただし、これを UIViewController に設定しても、コードは実行されますが、プッシュもされません。SetsSectionController を NSObject から UIViewController に変更することはできません。

どうすればよいかわかりません。

アプリデリゲートからのプッシュをやめようとしています。

編集:以下で説明するスクリーンショット2 ここに画像の説明を入力

4

2 に答える 2

1

「使えない」ってどういうこと?UIViewController をサブクラス化したくない/許可されていないということですか、それともコンパイラ エラーが発生していますか? あなたの質問に対するあなたのコメントから:

SetsSectionController.h:12:34: Cannot find protocol declaration for 'UIViewController'

サブクラスを変更するために間違ったことを変更しています。例として:

#import <Foundation/Foundation.h>

@protocol foo <NSObject>
- (void) bar;
@end

@interface lolcats : NSObject <foo>
@end

スーパークラスを変更するには、コロンの後のクラス名を変更します。元。

@interface lolcats : NSObject <foo>

になる

@interface lolcats : UIViewController <foo>

そして、あなたはオフになって走っています。ただし、プロトコルのプロトコル要件を誤って変更した場合は、

@protocol foo <NSObject>

@protocol foo <UIViewController>

代わりに、または従うプロトコルを変更すると<UIViewController>、正確なエラーが発生します。プロトコルは、それに準拠するオブジェクトも NSObject プロトコルに準拠する必要があると述べており、NSObject もオブジェクトのタイプであるため、混乱する可能性があります。オブジェクトとプロトコルは別のものであり、すべてのオブジェクトは NSObject から継承するため、プロトコルを継承します。基本的には、「このプロトコルを使用するオブジェクトはオブジェクトでなければならない」と言っています。

なぜこれがうまくいくと思ったのですか?このオブジェクトは、いくつかのメソッドを含むプロトコルに準拠していることを示す単なる標準の NSObject です。なぜナビゲーション コントローラーのプロパティがあるのでしょうか? それは何からも継承していません。とにかく、エラーに基づいて、おそらく間違ったことを変更しただけです。コロンの後のスーパークラス クラス名を必ず変更してください。

于 2012-09-30T16:12:47.693 に答える
1

ここにはいくつかの問題があります。プロトコルとクラスについて誤解があり、また、善意ではあるが実際には必要以上に生活を困難にしているプロトコルと連携するアプリケーションも持っています。

あなたが対処している最初の問題は、プロトコルとクラスの違い、およびプロトコルの採用とクラスからの継承の違いを理解するためのいくつかの問題です。これは簡単なことではありません。基本的に、プロトコルはオブジェクトへの単なるインターフェースであり、クラスはインターフェースと実装の両方を提供します。つまり、プロトコルは呼び出すことができるメソッドの単なるリストであり、クラスはメソッドのリストであり、それらのメソッドを実行するためのコードでもあります。より完全な説明を得るには、ソースに直接アクセスする方がよいでしょう。おそらく、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それでも使いたいのであれば、実際にあなたの生活を困難ではなく楽にする形にするには、かなりのリファクタリングが必要になると思います. セクションごとの論理偏差の複雑さによっては、完全に破棄することもできます。しかし、それはまったく別の質問です。お役に立てれば!

于 2012-09-30T10:45:49.910 に答える