2

这是关于Objective-C中(^{})的两部分问题。我已经搜索了一些答案,但在 Google 或 SO 中没有出现任何内容。这个问题源于希望为 iOS 创建一个自定义 XML 布局引擎,支持块 - 这意味着我想解析 NSStrings 并在运行时创建一个块。

1)这甚至可能吗?如果是这样,怎么办?

在 上找不到太多内容NSString to Block,我认为原因可能是编译器如何处理块 - 所以我再次寻找答案但空手而归。所以:

2) 在 Objective-C 中编译时块会发生什么?

4

3 回答 3

5

块是两件事;在执行通过块时捕获的一大块可执行代码和状态。

即给定:

 myBlock = ^{ return someVariable + someOtherVariable; };

编译后,这会创建一段代码,其行为非常类似于将两个变量相加返回结果的函数。没有创建块实例。

执行时,当计算表达式时myBlock = ^{...};,会创建一个块实例。在该块实例内部是对编译器创建的代码的引用,以及在进行赋值时两个变量中myBlock包含的值的副本(当然,除非__block正在运行,等等)。

这回答(2),但与回答(1)相关。

在运行时,您可以整天创建现有的、已编译的块的实例。但是,您不能创建新类型的块。这样做需要一个编译器,并且仅限于可以编译新的可执行代码并实际执行它的运行时环境。

于 2013-05-01T17:37:46.840 回答
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 以返回这些块。这对于递归下降解析器来说尤其简单。

于 2013-05-01T17:41:24.340 回答
0

1)如果你的意思是在运行时编译一个块,不。编译器在运行时不可用。2)显然,一个块是在编译时编译的。它是运行时的可执行代码,如函数或方法或其中任何一个的一部分。但是块的编译方式可以发送它们以进行后期执行和处理块变量魔法。

于 2013-05-01T17:43:56.417 回答