iOS問題記録帳:セルをクリックしているときにUITableViewがデータを更新し、クラッシュを引き起こす

0.背景説明

プロジェクトにはリストデータを表示する機能があり、リストには検索ボックスがあり、リスト内のデータをフィルタリングできます。
2か月前にオンラインになった後、Youmengの​​間違った統計で、少量の空の配列フェッチがフラッシュバックしたことが発見されました。

1.問題の発見

クラッシュはUITableViewのdidSelectRowコードメソッドで生成されますが、私のビジネスコードは、データ配列から数値をフェッチする前に境界を判断するためです。

if (indexPath.row<=self.dataArray.count-1) {
    NSDictionary *dict = self.dataArray[indexPath.row];
}

しかし実際には、フェッチ時にまだクラッシュしていました。
この機能は非常にシンプルで一般的であるため、検索機能に疑いを向けました。検索ボックスに入力すると、キーボードのポップアップが表示されるため、一部のモデルではキーボードがクラッシュするのではないかとさえ思っていました。 。
幸いなことに、問題は後で同僚の携帯電話で再現され、その後、継続的な実験を通じて問題を見つける必要があります。操作手順は次のとおりです。
インターフェイスに入る->検索ボックスをクリックしてキーボードをポップアップし、中国語の入力方法であることを確認します->入力された文字はまだ中国語の代替状態であるため、didChangeこの時点では、検索ボックスのコードメソッドはトリガーされません->次に、リストのセル->を直接クリックすると、コードはUITableViewのdidSelectRowメソッドに入ります。このメソッドでは、最初にキーボードを非表示にしてから、独自の処理を行います。ビジネスの論理。
ここで問題が発生します。最初にキーボードを非表示にしたため、検索ボックスのdidChangeイベントは、キーボードが非表示になった直後にトリガーされます。このイベントでは、リストデータをフィルタリングし、リストデータ配列を変更してから、reloadDataを実行します。ただし、上記の手順はすべて同期操作であるため、上記の手順を実行した後、didSelectRowメソッドの残りのコードが再度実行され、この時点でdataArrayは空になっています。
次に問題が発生します。dataArrayのカウントが0でindexPathが0-0の場合indexPath.row<=self.dataArray.count-1、式の結果はtrueになり、次のデータフェッチコードが入力されてクラッシュが発生します。

2.問題の原因

上記の分析を通じて、上記の状況下で、システムは0 <= 0-1が有効であると信じていることがわかります。
したがって、indexPath.row自体のタイプに問題があり、-1と比較すると常にtrueになるのではないかと疑う必要があります。
次に、indexPath.rowにNSNumberに変換して再度戻すように強制しましたが、問題を解決できませんでした。
戻って、indexPath.row<=self.dataArray.count-1<=-優先順位が2つの演算子を発行することさえ疑っています......
最後に、式が変更されindexPath.row+1<=self.dataArray.count、最終的にシステムがfalseに戻ります。
したがって、UITableViewのdidSelectRowイベントでUITableViewを更新すると、保持しているNSIndexPathオブジェクトに問題が発生し、indexPath.rowが通常のNSInteger値ではなくなったと思われます。この値を+1計算すると、再び正常値になりますので、比較結果は正常です。

3.解決策

3.1根本原因を解決する

問題の根本的な原因は、UITableViewによって送信されるindexPathオブジェクトの問題です。そのため、レビューと処理のために問題をAppleに提出する必要があります。しかし、これでは問題をすぐに解決することはできません。

3.2症状

  1. UITableViewのコードメソッドでUITableViewのrefreshメソッドをトリガーしないでください。
  2. サイズを判断するためにindexPath.rowやその他の値を直接使用しないでください。
  3. 最初のポイントを完全に回避できない場合は、indexPath.rowおよびその他の数値判断の前にUITableViewの更新メソッドがトリガーされないようにする必要があります。たとえば、私のコードでは、didSelectRowメソッドの最後にあるキーボードを非表示にします。

おすすめ

転載: blog.csdn.net/jhq1990/article/details/80516793