首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Block如何捕获其封闭作用域之外的变量?

Block如何捕获其封闭作用域之外的变量?
EN

Stack Overflow用户
提问于 2013-07-23 23:01:00
回答 3查看 8.1K关注 0票数 15

我知道Objective-C块可以捕获和设置其封闭作用域之外的变量的值。它如何做到这一点呢?

EN

回答 3

Stack Overflow用户

发布于 2013-07-24 03:17:08

它实际上相当简单,在Clang的块实现规范中,在"Imported Variables"一节中进行了描述。

当编译器遇到如下代码块时:

代码语言:javascript
运行
复制
^{ if( numBalloons > numClowns) abort(); }

它创建了一个文字结构,其中包括--以及其他--两个在这里很重要的元素。块中有一个指向可执行代码的函数指针,块中引用的每个变量都有一个const字段。如下所示:

代码语言:javascript
运行
复制
struct __block_literal_1 {
    /* other fields */
    void (*invoke)(struct __block_literal_1 *);
    /* ... */
    const int numBalloons;
    const int numClowns;
};

请注意,invoke函数将接受指向此处定义的那种结构的指针;也就是说,块在执行其代码时传递自身。因此,代码可以访问结构的成员。

在声明之后,编译器立即创建块的定义,它只是使用引用的变量来初始化struct中的正确字段

代码语言:javascript
运行
复制
struct __block_literal_1 __block_literal_1 = {
    /* Other fields */
    __block_invoke_2,  /* This function was also created by the compiler. */
    /* ... */
    numBalloons,  /* These two are the exact same variables as */ 
    numClowns     /* those referred to in the Block literal that you wrote. *
 };

然后,在invoke函数中,与结构the_block->numBalloons的任何其他成员一样,对捕获的变量进行引用。

对象类型变量的情况稍微复杂一些,但也适用相同的原则。

票数 26
EN

Stack Overflow用户

发布于 2013-07-23 23:06:19

在块对象的代码体中,可以用五种不同的方式处理变量。

您可以引用三种标准类型的变量,就像从函数中引用一样:

  • 全局变量,包括
  • 全局函数的静态局部变量(从技术上讲,这些变量和参数不是来自封闭作用域

的变量和参数

块还支持另外两种类型的变量:

函数级的

  1. __block变量。这些值在块(和封闭范围)内是可变的,如果将任何引用块复制到heap.
  2. const导入中,它们都会被保留。

最后,在方法实现中,块可以引用Objective-C实例变量-参见对象和块变量。

以下规则适用于块中使用的变量:

可以访问非静态全局变量,包括存在于传递给块的封闭词法scope.

  • Parameters中的静态变量(就像function).

  • Stack (非静态)的参数一样,封闭词法作用域的局部变量被捕获为变量。

它们的值是在程序中的块表达式的点上获取的。在嵌套块中,使用__block存储修饰符声明的封闭词法作用域是通过引用提供的,因此是可变的,值是从最接近的封闭scope.

  • Variables捕获的。

任何更改都会反映在封闭词法作用域中,包括在同一封闭词法作用域中定义的任何其他块。在块的词法范围内声明的

  • 局部变量在__block存储类型中进行了更详细的讨论,它们的行为与函数中的局部变量完全相同。

每次调用该块都会提供该变量的一个新副本。这些变量又可以在块内的块中用作const或引用变量。

从这里开始:

http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/Blocks/Articles/bxVariables.html

票数 6
EN

Stack Overflow用户

发布于 2013-07-24 09:06:01

基本上,块" object“在块对象内包含一个变量(类似于块对象的”实例变量“),用于每个捕获的局部变量。(Josh Caswell的回答提供了有关如何实现它的更多细节。)当创建块时,此时捕获的每个局部变量的值被复制到块内的相应变量中。无论何时在块内使用该变量,它都会在块内使用该变量。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17813870

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档