-1

Apple Store にアプリを提出しましたが、合格しました。しかし、アプリがクラッシュするバグがあることがわかりました。最後に、本当の問題は、コードのスナップが逆の結果をもたらすことであることがわかりました。

コード:

CGPoint now;
CGPoint old;
UIView *lastDot;
now = dotView.center;
if(lastDot){
    //release version, will go here. then crashed.
    old = lastDot.center;
}else{
    //debug version, will go here. run ok.
}

UIViewポインタを宣言し、if文でチェックして、

UIView *lastDot;

デバッグ バージョンは lastDot を nil と見なしますが、リリース バージョンは null ではないと見なします。

誰かが私に何か考えを与えることができますか? ありがとうございました。

4

2 に答える 2

6

コンパイラの設定に応じて、デバッグ ビルドは通常、 のようなセンチネル値へのポインターを初期化します0xcccccccc

UIView *lastDot = nil;

期待どおりに動作するはずです。

于 2013-01-16T02:27:00.130 に答える
1

この問題は、ポインタが初期化されていないことが原因です。

このようなトラブルを避けるために、nil に初期化してください。

UIView *lastDot = nil;

私はあなたがすでに答えを得ていることを知っています.

私もいくつかのポイントを追加したいだけです:

ポインターは他の変数と同じです。明示的に値を設定しないと、値は未定義になり、ランダムな値になります。その後、変数に誤ってアクセスすると、非常に悪いことが起こる可能性があります。

多くのコードがすでに NULL ポインターをチェックしているため、ポインターを NULL に割り当てることをお勧めすることがあります。たとえば、 を呼び出すと[nil release]、何もしないことが保証されます。初期化されていないポインターを渡した場合、何が起こるかは誰にもわかりません。

これは、プログラマーのエラーに対する保護手段にすぎません。ポインターを適切な値に初期化すると、初期化されていないポインターが原因で将来システム クラッシュが発生する可能性が低くなります。

ポインターを初期化せずに使用しようとすると、次の 3 つの問題があります。

  • アクセスできないメモリを指している可能性があります。その場合、セグメンテーション違反が発生し、プログラムがクラッシュします
  • 実際のデータを指している可能性があり、それが何を指しているかわからない場合は、データに予測不可能な (そしてデバッグが非常に困難な) 変更を引き起こしています。
  • 初期化されているかどうかを知る方法はありません。有効なアドレスと、ポインターを宣言したときにたまたまそこにあったアドレスとの違いをどのように見分けるのでしょうか?

すべてのポインターを初期化するとnil、これらの問題が大幅に減少または解消されます。

  • 使用しようとすると、まだセグメンテーション違反になりますが、少なくとも NULL かどうかをテストして、それに応じて行動することができます。ランダムな値なら、クラッシュするまで何もわかりません。
  • に初期化するとnil、明示的に指示しない限り、データを指すようにすることはできません。だから私は自分が意図したものだけを修正します。
  • 上で暗示されているように、いつ初期化したか、いつ初期化していないかを判断して、決定を下すことができます。

明らかにスタイルの問題であり、変数が意図した値にのみ初期化されるアプリケーションを作成することは可能ですが、変数をnil 常に初期化する方が安全で簡単だと思います。最高のプログラマーでさえタイプミスをします -nilそれがいつ起こったのかをより簡単に知ることができます.

参照 :

  1. エスキモー
  2. 常に必要なポインタの初期化
于 2013-01-16T04:24:35.467 に答える