我正在写一个简单的QR code生成器(只是为了好玩和学习一些Obj-C),我正在研究连接的“模块”的轮廓(即构成的黑色方块)一个二维码)。这是为了获得更好的矢量输出,而不是简单地为每个模块制作一堆rects。
长话短说,我的大纲跟踪代码有效 - 但是,如果我确保在特定的地方调用NSLog!如果我删除NSLog
- 调用,代码循环!我实际上除了记录之外什么都不做。我记录的内容并不重要;我只需要打电话给NSLog或者事情就好了。
跟踪算法很简单:顺时针绕连接模块的形状移动。当你碰到一个角落时,向右转,直到你回到跟随形状的轮廓。再次到达起点时停止。形状可以有两个共享角点的模块。因此,跟踪循环将达到该点两次。这是预期的,代码正确处理它 - 如果我调用NSLog
。
否则,代码会在第一次看到它时说某个点是一个角落,第二次不一个角落,这会导致跟踪循环。检测是否某个角点不依赖于除了点的x和y坐标以及模块对象数组之外的任何东西 - 但是在跟踪进行时模块和数组都没有变化,所以给定相同的x,你应该总是得到相同的结果。它确实 - 如果我打电话给NSLog
。
没有NSLog
,坐标 - 例如(10,9) - 是时刻的角落,片刻之后(10,9)突然不被识别为角落。但 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使代码中断),我很乐意听到它!我希望有人能理解它。
答案 0 :(得分:7)
确保cornerAtX:Y:
总是返回一些内容,即没有代码路径无法返回值。
否则,无论你调用的最后一个函数返回什么,它都可以很好地“返回”,在这种情况下,调用NSLog
(它不会返回一个值,但可能最终调用一个函数)会导致它“回归”不同的东西,这可能总是被认为是真实的东西。
如果您未能从声明为这样做的函数或方法返回值,编译器应该发出警告。你应该听听它。 Turn on all the warnings you can get away with and fix all of them.
你也应该打开静态分析器(也包括在那篇文章中),因为它也可以告诉你这个bug,如果有的话,它会告诉你它是如何发生的。< / p>
答案 1 :(得分:2)
这里没什么可说的,但我猜它是一个未初始化的变量或某种内存踩踏。 NSLog可能同时使用堆栈和堆内存,因此可能会影响这些内存。
答案 2 :(得分:0)
您是否尝试过用其他一些无意义的操作替换NSLog?如果这也有效,那么我认为问题与[self cornerAtX:x Y:y]有关。 另一种可能性是问题与时间有关。 NSLog需要时间来执行,所以如果在另一个线程中加载QR码,你可以看到这种行为。