我正在努力解决代码“执行顺序”的概念,到目前为止,我的研究已经很短暂。我不确定我是否错误地表达了它,这个概念可能有更合适的术语。如果有人能对我下面的各种绊脚石有所了解,我会很感激。
我明白如果你一个接一个地调用一个方法:
[self generateGrid1];
[self generateGrid2];
两种方法都在运行,但generateGrid1不一定等待generateGrid2。但是,如果我需要它呢?假设generateGrid1执行一些复杂的计算(需要花费未知的时间)并填充generateGrid2用于计算的数组?这需要在每次触发事件时完成,这不仅仅是一次初始化。
我需要一种顺序调用方法的方法,但是有一些方法可以等待其他方法。我已经调查了回调,但在我见过的所有例子中,这个概念总是与代表结婚。
我也不确定何时确定我无法合理地期望及时解析一行代码以供其使用。例如:
int myVar = [self complexFloatCalculation];
if (myVar <= 10.0f) {} else {}
我如何确定是否需要花费足够长的时间来实施“在开始我的事情之前完成其他事情”的检查。只是反复试验?
或者我可能正在将方法作为另一种方法的参数传递?是否等待在执行方法之前评估参数?
[self getNameForValue:[self getIntValue]];
答案 0 :(得分:6)
我明白如果你一个接一个地调用一个方法:
[self generateGrid1]; [self generateGrid2];
两种方法都在运行,但generateGrid1不一定等待generateGrid2。但是,如果我需要它呢?
假。 generateGrid1
将运行,然后generateGrid2
将运行。这种顺序执行是程序语言的基础。
从技术上讲,允许编译器重新排列语句,但如果最终结果与原始结果无法区分,则仅。例如,请查看以下代码:
int x = 3;
int y = 4;
x = x + 6;
y = y - 1;
int z = x + y;
printf("z is %d", z);
首先发生x+6
或y-1
行是否无关紧要;代码写为不会使用除计算z
之外的任何中间值,并且可以按任意顺序发生。因此,如果编译器可以出于某种原因通过重新排列这些行来生成更高效的代码,则允许这样做。
但是,您永远无法看到此类重新排列的效果,因为只要您尝试使用其中一个中间值(例如,记录它),编译器就会识别出该值正在被使用,并摆脱会破坏你的日志记录的优化。
实际上,编译器不需要按照提供的顺序执行代码;只需要生成与您提供的代码功能相同的代码。这意味着,如果将调试器附加到使用优化编译的程序,那么实际上可以看到这些优化的效果。这导致了各种令人困惑的事情,因为调试器跟踪的源代码不一定与编译器生成的编译代码的代码逐行匹配。这就是为什么程序的调试版本几乎总是关闭优化的原因。
无论如何,关键在于编译器只有在能够证明没有效果时才能执行这些技巧。 Objective-c方法调用是动态绑定的,这意味着编译器完全无法保证在调用该方法时在运行时实际发生的事情。由于编译器无法保证将会发生什么,因此编译器永远不会重新排序Objective-C方法调用。但同样,这又回到了我之前所说的相同原则:编译器可能会改变执行顺序,但前提是用户完全无法察觉。
换句话说,不要担心。您的代码将始终从上到下运行,每个语句都在等待完成之前的语句。
答案 1 :(得分:5)
通常,您在所描述的样式中看到的大多数方法调用都是同步,这意味着它们将具有您想要的效果,按照语句编码的顺序运行,其中第二个第一次通话完成并返回后,电话只会运行。
此外,当方法接受参数时,在调用方法之前,会对其参数进行求值。