web-dev-qa-db-ja.com

このエラーの原因は何ですか? 「CALayerの位置にはNaNが含まれています:[240 nan]」

これは、UITableViewが表示されている画面を回転させるたびに発生します。 willRotatedidRotateメソッド呼び出しとUIViewControllerメソッド呼び出しの間に発生することがわかりました。同僚も他の場所で、通常は回転の周りでそれを見てきました。それはごく最近まで発生し始めていませんでしたが、私たちはそれをどう扱うべきか迷っています(Google検索は正確な形式でエラーメッセージを表示しません)。他の誰かがこれに遭遇しましたが、それについて何をすべきかを知っていますか?

46
Kevlar

問題が見つかりました。

tableviewのフレームをリセットすると、デリゲートメソッドtableView:heightForRowAtIndexPath:は、必要に応じてコンテンツサイズを再計算できるように、テーブルの各行に対して使用します。その時点で、特別な処理を行って高さを返しますが、コードのいくつかの悪い仮定のために、ゼロ除算エラーのためにNaNを誤って返しました(除算する変数はゼロではないと想定されていました)。ここでゼロで除算しないことを確認して修正しました。

26
Kevlar

(コメントからこれを取り出して、答えとして置くことにしました。なぜなら、それはあきれた良い答えだと思うからです:)

ハ! NaN計算(div0)もありました。主要なデバッグ支援:問題のメッセージはNSLog()によって出力されるため、NSLog()にブレークポイントを設定し、その時点でOSが何をしているかを監視します。私にとっては、myUISlider.value = NaNでした。

ブレークポイントを設定するには:

XCode 3.x

  • CMD-SHIFT-Y(デバッグウィンドウ。)
  • ブレークポイントボタン。
  • 「シンボルをダブルクリック」
  • 「NSLog」と入力します(引用符なし)。

XCode 4.x

  • CMD-6(ブレークポイントナビゲーター。)
  • ブレークポイントを追加するには「+」(左下)。
  • [シンボルブレークポイントの追加]を選択します。
  • シンボル:NSLog
  • 確認:完了。

XCode 5.x-7.1(少なくとも)(4.xと同じ、ただし、ブレークポイントナビゲーターはCMD-7になりました。)

アプリを実行し、NSLogで壊れるのを見て、スタックトレースを確認します。

36
Olie

同じ問題の原因となるコードを見つけようとして1日を費やし、Xcodeで「例外でブレーク」を有効にしてから数分以内に解決しました。 このチュートリアル をチェックして、有効にする方法を確認してください。

15
azernitsky

私はそれを仮定したときにこの問題がありました:

tableView:heightForHeaderInSection:NSIntegerを返しましたが、CGFloat...を返します...

変化:

-(NSInteger)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section

-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section

私の問題を修正しました。

編集:

ある時点で、コンピューターがCレベル以下でどのように動作するかを見つけたので、共有すると思いました...(x86_64のレジスター名を使用します。最もよく知っているので、ARMはわずかに異なるが類似)

int f(){
          float someFloat=5.0f;
          return someFloat;
       }

someFloatの値を整数型に変換し、それを特定のレジスタにコピーします:%raxその後、リターン命令を呼び出します。

float f(){
          float someFloat=5.0f;
          return someFloat;
       }

someFloatの値を現在の場所から特定のレジスタ%xmm0にコピーしてから、リターン命令を呼び出します。

そのため、間違ったプロトタイプがある場合、呼び出し元のコードは値が間違った場所にあることを期待し、実際にはガベージ値を返すことになります。

12
Grady Player

また、このエラーには時間がかかりました。
最後に、同僚が次のように書いているのを見つけました。

UIEdgeInsets a;
a.left = (...some calculation);
button.imageEdgeInsets = a;

そして、これらのコードを次のように書き直し、問題を修正しました。

UIEdgeInsets a;
a.left = (...some calculation);
a.top = 0;
a.bottom = 0;
a.right = 0;
button.imageEdgeInsets = a;

uIEdgeInsetsの一部の値は適切に初期化されず、NaN値になり、アプリケーションがクラッシュすることがあります。
より一般的には、Cスタイル構造体のすべての値が適切に初期化されているかどうかを確認する必要があります。

2
Z.L.Chen

問題を再現する別の方法があります:小さすぎる長方形でinsetBy(dx:dy:)を使用する

enter image description here

0
Tim

これを試すことができますyourTableview?.bounces = false。わたしにはできる。

0
kalpesh