0

私はにUITableView支えられていNSArrayます。

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
  return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
  return self.data.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  static NSString *CellIdentifier = @"CellIdentifier";
  UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:CellIdentifier];
  if (cell == nil) {
      cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];

  }
  id item = [self.data objectAtIndex:indexPath.row];
  cell.item = item;

  return cell;
}

非常に標準的です。ここで問題とreloadDataなるのは、同期的に要求しますがnumberOfSections、非同期numberOfRows的に呼び出すことcellForRowです。そのため、cellForRowAtIndexPath呼び出されるまでにデータ配列が変更さ[self.data objectAtIndex:indexPath.row]れ、範囲外の例外が発生してアプリがクラッシュすることがあります。これを回避するにはどうすればよいですか?

配列を設定するたびにdata、も呼び出すことに注意してください[self.tableView reloadData]

4

4 に答える 4

0

変更されないローカル配列を格納する必要があります。その後、ベースアレイが変更されたときに、保存されたアレイを安全に更新できます。組み込みのAPIを使用して、テーブルビューからセルを追加/削除する方法を調べます。既存のUITableViewセクションに行を追加します。

于 2012-10-18T15:22:20.507 に答える
0

cellForRowAtIndexPath頻繁に呼び出される場合(スクロールなど)、単純なコード行を追加するだけで、データ配列のサイズが要求されているセルよりも小さいかどうかを確認できます。これは、空白のセルになってしまう可能性があることを意味します。

両方のメソッドにブレークポイントを設定し、ブレークポイントを右クリックして[ブレークポイントを編集]をクリックし、[評価後に自動的に続行する]にチェックマークを付けます。次に、「アクションの追加」->「デバッガコマンド」をクリックし、「podata」または「po[datacount]」と入力します。

これにより、ブレークポイントに到達するたびに(停止せずに)、デバッグコンソールに配列に関する情報が出力されます。これで、デバッグ出力を調べて、同期が外れている場所を確認できるはずです。にいくつかのステートメントを追加NSLogして、どのメソッドが呼び出されているかなどを通知し、そこから作業します。

于 2012-10-17T23:52:07.303 に答える
0

私が使用したクイックハック、これを試して、それがうまくいくかどうかを確認してください:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  static NSString *CellIdentifier = @"CellIdentifier";
  UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:CellIdentifier];
  if (cell == nil) {
      cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];

  }

  // -----------------------------------------------------------------
  // the magical line that prevents the table from fetching the data
  // -----------------------------------------------------------------
  if([indexPath row] < [self.data count])
  {

      id item = [self.data objectAtIndex:indexPath.row];
      cell.item = item;
  }

  return cell;
}

:D

于 2012-10-18T08:34:45.803 に答える
0

このような状況を回避する最善の方法は、データが更新されている間はユーザーの操作を避けることだと思います.「更新中..」という画面とアクティビティインジケーターをユーザーに表示することができます.

もう 1 つの方法は、別の配列を使用して新しいデータを入力することです。別のスレッドで処理を行うことができ、その後、リロード呼び出しでデータソース配列に割り当てられるだけです。データソース配列中に同じ画面を使用することもできます。変わる

于 2012-10-18T05:17:01.387 に答える