私は単純なQR コードジェネレーターを作成しており (楽しみと Obj-C の学習のため)、接続された "モジュール" (つまり、QR コードを構成する黒い四角形) のアウトラインをトレースする作業を行っています。これは、単純にモジュールごとに多数の四角形を作成するよりも優れたベクトル出力を得るためです。
簡単に言うと、私のアウトライン トレース コードは機能しますが、特定の場所で NSLog を確実に呼び出す場合にのみ機能します。-callを削除するNSLog
と、コードがループします。私は文字通り、ログ記録以外は何もしていません。何をログに記録するかは問題ではありません。NSLog を呼び出す必要があるか、問題が発生します。
トレース アルゴリズムは単純です。接続されたモジュールの形状を時計回りに進みます。角にぶつかったら、形状の輪郭に戻るまで右に曲がります。再び開始点に到達したら停止します。シェイプには、コーナー ポイントを共有する 2 つのモジュールを含めることができます。したがって、トレース ループはそのポイントに 2 回到達します。これは予想されることであり、コードはそれを正しく処理しますNSLog
。
それ以外の場合、コードは特定のポイントを最初に見たときにコーナーであると判断し、2 回目にはコーナーではないと判断し、トレースがループします。何かがコーナーポイントであるかどうかの検出は、ポイントの x 座標と y 座標、およびモジュール オブジェクトの配列以外には依存しませんが、トレースの実行中にモジュールも配列も変更されないため、同じ x を指定すると、 y常に同じ結果が得られるはずです。そして、それは -私が呼び出す場合NSLog
。
がないNSLog
場合、座標 (たとえば (10,9)) はすぐに角になり、その瞬間 (10,9) は突然角として識別されなくなります。しかし、 -call を使用するとNSLog
、(10,9) は常にコーナーポイントとして正しく認識されます。
繰り返しますが、私はまったく何も変更しません。私はただ何かを記録します - 何でも!そして突然それは機能します。2 == 2 が trueまたはfalse であると言っているようなものです。ただし、2 と 2 をログに記録するように指示しない限り、その場合、2 == 2 は常に true である必要があります。
これが不安定なコードです。文脈がわからなくてわかりにくいですが、文脈がたくさんあるので、これで十分だと思います。すべてが整数です (ファジー浮動小数点値はありません)。
do { // start going around the shape
// If this isn't here or simply commented out, the code loops.
NSLog(@"foobar"); // doesn't matter what I log - I just need to log something
// Branch: Is current x,y a corner-point? This should
// always return the same result given the same X and Y
// values, but it only does if NSLog is there!
if( [self cornerAtX:x Y:y] ) {
// add the point to the path
[path addPoint:NSMakePoint(x, y)];
// rotate the direction clockwise, until
// the direction is following the edge of the
// the shape again.
do {
dt = dx;
dx = -dy;
dy = dt;
} while( ![self boundaryFromX:x Y:y inDirectionX:dx Y:dy] );
}
// continue along direction
x += dx;
y += dy;
} while( !(sx == x && sy == y) ); // we're back to the start of the shape, so stop
なぜ NSLog がコードを機能させることができるのか (または、なぜNSLog を使用しないとコードが機能しなくなるのか) を誰かが教えてくれれば、喜んでそれを聞きます! 誰かがそれを理解できることを願っています。