2

私はregisterNib:forCellReuseIdentifier:を使用して nib b/c からセルをロードしています。これにより、いつでも [tableView dequeueReusableCellWithIdentifier:] からセルを取得できるため、定型コードを減らすことができると言われました。

私は常にセルを取得しますが、問題は、IBAction (セル内のボタン) が例外「NSInvalidArgumentException」を発生させて失敗し始めたことです。理由: xxx認識されないセレクターがインスタンスに送信されました。

registerNib:forCellReuseIdentifier: の呼び出しを削除し、通常どおりこれらのコードを追加すると (以下)、すべて正常に動作します。したがって、問題はこの呼び出しによって引き起こされたと思います。

それで、私は何を間違えましたか?

ところで、セルnibファイルのファイル所有者をテーブルビューコントローラーに設定しました。この場合、「IOS 5 のプログラミング」では「nib でファイルの所有者クラスを指定する必要はありません」とありましたが、IBAction を設定する必要があるため、まだ設定しています。これが問題を引き起こすとは思いませんよね?

//The "old" codes without calling registerNib:forCellReuseIdentifier:
UITableViewCell *cell =[tableView dequeueReusableCellWithIdentifier:@"MyCell"];
if (cell == nil) {
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"MyCell"
                                                 owner:self 
                                               options:nil];
    cell = [nib objectAtIndex:0];

...

4

3 に答える 3

1

あなたの IBAction は、セルをロードするコントローラーにありますね。それがうまくいくとは思わないでください。デキュー時にコール スタックを見ると (私が現在デバッグのスポットで行っているように)、次のことがわかります。

- [YOURCELLCLASS awakeFromNib];
- [UINib instantiateWithOwner:options:]
- [UITableView dequeueReusableCellWithIdentifier:]

テーブルビューは、宣言したクラスと一致するように、どのコントローラーオブジェクトを所有者として UINib に渡す必要があるかをどのように認識しますか? それを行う方法はないようです。実際、上記のボタンを複製して -awakeFromNib でそのターゲットを確認すると、そのターゲットは間違いなくコントローラーではありません。したがって、あなたのクラッシュ。興味深いことに、テーブル ビューでもないようです。これは私が期待していたものです。これは一見しただけでは明らかなアドレスと一致しない NSObject です。

肩をすくめるとにかく、教訓は、この xib ではファイルの所有者を使用してはならないということのようです。ロジックをセルのカスタム クラスに移動するか、デキュー後にコントロールのターゲットを自分で設定します。

于 2012-08-31T18:58:31.730 に答える
0

IB を使用してアクションを接続する場合は、主に 2 つのオプションがあると思います。

  1. 使用しないでください-古いスタイルのコードを使用してregisterNib:forCellReuseIdentifier:手動でペン先をロードしてください。cellForRowAtIndexPath:
  2. Guy English のアドバイスに著しく違反して、IBActions を Files Owner ではなく First Responder に送信します。
于 2014-10-01T14:45:45.730 に答える
0

私は再び問題にぶつかり、さらに調査を行いました。そして、ここに私が見つけたものがあります、

  1. セルペン先にファイル独自のものを設定することは無意味です(そして危険です)。IBAction を MyCell クラスに接続するために xib にファイル独自のものを設定しましたが、[[NSBundle mainBundle] loadNibNamed:owner:options:] で提供された所有者が唯一のランタイムであることに気付きました。MyCell に 1 つ、所有者にもう 1 つ、2 つの IBActions (同じメソッド名) を提供し、どちらが呼び出されたかを確認するだけで簡単に確認できます。
  2. 呼び出してセルを作成できるという記事がたくさんありますが、cell = [[MyCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];これは間違っていたと思います。xib ファイルのセルを使用するには、呼び出す必要があります[[NSBundle mainBundle] loadNibNamed:owner:options:]
  3. これは、使用registerNib:forCellReuseIdentifier:すると IBAction が間違ったターゲットに設定されるか、IBAction と一緒に使用できないというバグだと思います。@alexcurylo が使用したときに言ったように、ファイルの所有者を正しく設定する方法はありません (xib で設定したとしても)。ここでの質問への答えUITableView registerNib:forCellReuseIdentifier:ランタイムは所有者をnilに設定しただけです。しかし奇妙なことに、IBOutlet は常に正しく設定されています。
  4. したがって、IBOutlet のプロパティを更新するだけでよい場合、たとえば UILabel のテキストを更新する場合は、 registerNib:forCellReuseIdentifier: を使用する方が簡単です。ただし、アクションが必要な場合はaddTarget:action:、UIView を取得した後に呼び出す必要があります ([[NSBundle mainBundle] loadNibNamed:owner:options:] または registerNib:forCellReuseIdentifier:)
  5. カスタマイズされたテーブル セルを作成するには、UITableViewCell をサブクラス化してコントロールをコードに配置するか、セル xib ファイルを使用するだけでかまいませんが、両方を行う必要はありません (多くの記事でも提案されています)。IBAction を正しく取得できず、IBOutlet なしでサブビューを簡単に取得できるためです。xib を使用する方がおそらく簡単です。xib ファイルを使用するときは、サブビューのタグをセルに設定することを忘れないでください。[cell viewWithTag:] で UIView を取得できます。
于 2013-04-08T15:15:49.260 に答える