这是关于Objective-C中块(^{})的两部分问题。我已经搜索了一些答案,但在 Google 或 SO 中没有出现任何内容。这个问题源于希望为 iOS 创建一个自定义 XML 布局引擎,支持块 - 这意味着我想解析 NSStrings 并在运行时创建一个块。
1)这甚至可能吗?如果是这样,怎么办?
在 上找不到太多内容NSString to Block,我认为原因可能是编译器如何处理块 - 所以我再次寻找答案但空手而归。所以:
2) 在 Objective-C 中编译时块会发生什么?
这是关于Objective-C中块(^{})的两部分问题。我已经搜索了一些答案,但在 Google 或 SO 中没有出现任何内容。这个问题源于希望为 iOS 创建一个自定义 XML 布局引擎,支持块 - 这意味着我想解析 NSStrings 并在运行时创建一个块。
1)这甚至可能吗?如果是这样,怎么办?
在 上找不到太多内容NSString to Block,我认为原因可能是编译器如何处理块 - 所以我再次寻找答案但空手而归。所以:
2) 在 Objective-C 中编译时块会发生什么?
块是两件事;在执行通过块时捕获的一大块可执行代码和状态。
即给定:
myBlock = ^{ return someVariable + someOtherVariable; };
编译后,这会创建一段代码,其行为非常类似于将两个变量相加返回结果的函数。没有创建块实例。
执行时,当计算表达式时myBlock = ^{...};,会创建一个块实例。在该块实例内部是对编译器创建的代码的引用,以及在进行赋值时两个变量中myBlock包含的值的副本(当然,除非__block正在运行,等等)。
这回答(2),但与回答(1)相关。
在运行时,您可以整天创建现有的、已编译的块的实例。但是,您不能创建新类型的块。这样做需要一个编译器,并且仅限于可以编译新的可执行代码并实际执行它的运行时环境。
您不能轻易做的是在运行时编译 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 以返回这些块。这对于递归下降解析器来说尤其简单。
1)如果你的意思是在运行时编译一个块,不。编译器在运行时不可用。2)显然,一个块是在编译时编译的。它是运行时的可执行代码,如函数或方法或其中任何一个的一部分。但是块的编译方式可以发送它们以进行后期执行和处理块变量魔法。