Код работает только если я NSLog некоторые значения - но почему? - PullRequest
2 голосов
/ 22 ноября 2010

Я пишу простой QR-код генератор (просто для развлечения и изучения Obj-C), и я работаю над отслеживанием контура подключенных «модулей» (то есть черных квадратов) что составляет QR-код). Это сделано для того, чтобы получить более качественный векторный вывод, чем просто сделать кучу канатов для каждого модуля.

Короче говоря, мой код трассировки контуров работает - НО ТОЛЬКО если я обязательно вызову NSLog в определенном месте! Если я удаляю NSLog -call, код зацикливается! Я буквально ничего не делаю, кроме регистрации. И не важно, что я регистрирую; Мне просто нужно позвонить в NSLog или все сломалось.

Алгоритм трассировки достаточно прост: идите по часовой стрелке вокруг формы подключенных модулей. Когда вы нажмете угол, поверните направо, пока не вернетесь к следованию контуру фигуры. Остановитесь, когда достигнете начальной точки снова. Форма может иметь два модуля, которые имеют общую угловую точку. Таким образом, контур трассировки дважды достигнет этой точки. Это ожидается, и код обрабатывает это правильно - , если , я звоню NSLog.

В противном случае код скажет, что определенная точка является углом в первый раз, когда она ее видит, а не угол во второй раз, что приводит к циклическому обходу трассировки. Обнаружение того, что что-то является угловой точкой, не зависит ни от чего, кроме координат x и y точки и массива объектов модулей - но ни модули, ни массив не изменяются во время отслеживания, поэтому при наличии того же самого x, y вы должны всегда получать один и тот же результат. И это делает - , если я звоню NSLog.

Без NSLog, координаты - например, (10,9) - это угловой момент, а мгновение спустя (10,9) внезапно не a идентифицируется как угол. Но с и NSLog -телефонным вызовом (10,9) правильно каждый раз рассматривается как точка отсчета.

Опять же: я абсолютно ничего не меняю; Я просто что-то регистрирую - что угодно! И вдруг это работает. Как будто говорят, что 2 == 2 истинно или ложно, если я не сообщу это лог 2 и 2, и в этом случае 2 == 2 всегда верно, как и должно быть.

Вот ненадежный код. Это трудно понять вне контекста, но есть много контекста, поэтому я надеюсь, что этого достаточно. Все целые числа (нет нечетких значений с плавающей точкой).

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 делает рабочий код неработоспособным), я был бы рад это услышать! Я надеюсь, что кто-то может понять это.

Ответы [ 3 ]

7 голосов
/ 22 ноября 2010

Убедитесь, что cornerAtX:Y: всегда что-то возвращает, т. Е. Что нет пути к коду, который не может вернуть значение.

В противном случае он может очень хорошо «возвратить» любую последнюю вызванную вами функцию,в этом случае вызов NSLog (который не возвращает значение, но в конечном итоге может вызвать функцию, которая его выполняет) заставляет его «возвращать» что-то другое, что всегда может быть чем-то, что считается истинным.должен предупредить вас, если вам не удастся вернуть значение из функции или метода, которые вы объявили как таковые.Вы должны слушать это. Включите все предупреждения, которые вы можете избежать, и исправьте их все.

Вам также следует включить статический анализатор (также включенный в этот пост), так как он также можетрасскажет вам об этой ошибке, и если она это сделает, она расскажет вам шаг за шагом, как она происходит.

2 голосов
/ 22 ноября 2010

Здесь не так много всего, но я бы предположил, что это либо неинициализированная переменная, либо какое-то вытеснение памяти.NSLog, вероятно, использует как стек, так и кучную память, так что это может повлиять на них.

0 голосов
/ 22 ноября 2010

Вы пытались заменить NSLog другой бессмысленной операцией?Если это также сработает, то я предполагаю, что проблема связана с [self cornerAtX: x Y: y].Другая возможность заключается в том, что проблема связана со временем.NSLog требует времени для выполнения, поэтому, если QR-код загружен в другой поток, вы можете увидеть такое поведение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...