这是关于 Objective-C 中 blocks (^ {})的两部分问题。我已经搜索了一些答案,但没有任何内容出现在Google或SO中。这个问题源于为iOS创建自定义XML Layout Engine的愿望,支持块 - 这意味着我想解析NSStrings并在运行时创建一个块。
1)这甚至可能吗?如果是这样,怎么办呢?
在NSString to Block
上找不到多少,我认为原因可能是编译器如何处理一个块 - 所以我再次搜索一个答案但空手而归。所以:
2)在Objective-C编译时块发生了什么?
答案 0 :(得分:5)
一个块是两件事;执行经过块时捕获的一大块可执行代码和状态。
即。给出:
myBlock = ^{ return someVariable + someOtherVariable; };
编译时,这会创建一个代码块,其行为非常类似于将两个变量一起添加的函数返回结果。没有创建块实例。
执行时,在计算表达式myBlock = ^{...};
时,会创建一个块实例。在该块实例内部是对编译器创建的代码的引用,以及在分配给myBlock
时两个变量中包含的值的副本(当然,除非__block
正在播放,等等......)。
答案(2),但与回答(1)有关。
在运行时,您可以整天创建现有的,已编译的块的实例。但是,您无法创建新的种块。这样做需要编译器,并且仅限于编译新的可执行代码并实际执行它的运行时环境。
答案 1 :(得分:0)
您不能轻易做的是在运行时编译Objective-C代码以创建块。你可以做的是为你的布局DSL创建一个小解析器并创建一个块树。例如,可以使用嵌套块实现数学表达式解析器。
以下是表达式“2 + 3 * 4”的示例:
typedef double(^MathBlock)(void);
MathBlock exprL = ^(void) { return 3.0; };
MathBlock exprR = ^(void) { return 4.0; };
exprR = ^(void) { return exprL() * exprR(); };
exprL = ^(void) { return 2.0; };
exprR = ^(void) { return exprL() + exprR(); };
double result = exprR();
显然,您需要编写解析函数来解释XML以返回这些块。使用递归下降解析器时,这一点特别简单。
答案 2 :(得分:0)
1)如果你的意思是在运行时编译一个块,没有。编译器在运行时不可用。 2)显然,在编译时编译一个块。它是运行时的可执行代码,如函数或方法或其中任何一部分。但是块的编译方式可以发送给后执行和处理块变量魔术。