[翻译] Blocks and Variables
Blocks and Variables

http://stackoverflow.com/questions/16149653/what-is-the-role-of-the-copy-in-the-arc
This article describes the interaction between blocks and variables, including memory management.
这篇文章描述了 blocks 与变量间的交互作用,同时也包括内存管理。
Types of Variable
Within the block object’s body of code, variables may be treated in five different ways.
在 block 对象体中插入的代码,变量可以分为5种。
You can reference three standard types of variable, just as you would from a function:
你可以引用 3 种标准类型的变量,就像你在普通方法中使用的那样子:
Global variables, including static locals 全局变量,包括 static 修饰过的静态变量
Global functions (which aren’t technically variables) 全局方法(技术上来说不能被称作变量)
Local variables and parameters from an enclosing scope 局部变量和从上下文中带进来的参数
Blocks also support two other types of variable:
Blocks 也支持另外两种类型的变量:
At function level are
__blockvariables. These are mutable within the block (and the enclosing scope) and are preserved if any referencing block is copied to the heap. 函数级别上的 __block 修饰的对象。它在block里面是可以修改的,如果这个 block 被 copy 到了栈区,这个对象就会被强引用。constimports. const引入的。
Finally, within a method implementation, blocks may reference Objective-C instance variables—see “Object and Block Variables.”
最终,在一个方法的实现当中,blocks 也许会强引用 Objective-C 实例变量,请参考 “Object and Block Variables.”
The following rules apply to variables used within a block:
以下规则适用于在 block 中使用的变量:
Global variables are accessible, including static variables that exist within the enclosing lexical scope. 可以接收全局变量,包括存在于上下文中的静态变量。
Parameters passed to the block are accessible (just like parameters to a function). 传递到 block 中的变量(就像函数传递参数一样)
Stack (non-static) variables local to the enclosing lexical scope are captured as
constvariables. 相对于 block 块的非静态堆区对象被识别为 const 对象。Their values are taken at the point of the block expression within the program. In nested blocks, the value is captured from the nearest enclosing scope. 他们的值会以指针的形式传递到 block 中。
Variables local to the enclosing lexical scope declared with the
__blockstorage modifier are provided by reference and so are mutable. __block 修饰的对象允许在 block 中进行修改,并会被 block 强引用。Any changes are reflected in the enclosing lexical scope, including any other blocks defined within the same enclosing lexical scope. These are discussed in more detail in “The __block Storage Type.”
Local variables declared within the lexical scope of the block, which behave exactly like local variables in a function. 在 block 块中实例化的对象,与在函数中实例化的对象基本一致。
Each invocation of the block provides a new copy of that variable. These variables can in turn be used as
constor by-reference variables in blocks enclosed within the block. 每一次调用这个 block 都会提供一个变量的 copy。相应的,这些对象可以被当做 const 或者是强引用的对象使用。
The following example illustrates the use of local non-static variables:
以下例子描述了如何使用一个本地非 static 的变量:
int x = 123; |
void (^printXAndY)(int) = ^(int y) {
|
printf("%d %d\n", x, y);
|
}; |
printXAndY(456); // prints: 123 456 |
As noted, trying to assign a new value to x within the block would result in an error:
正如提到的那样,给 x 在 block 中直接赋值会引发错误:
int x = 123; |
void (^printXAndY)(int) = ^(int y) {
|
x = x + y; // error |
printf("%d %d\n", x, y);
|
}; |
To allow a variable to be changed within a block, you use the __block storage type modifier—see “The __block Storage Type.”
为了允许一个变量在 block 中可以被修改,你需要使用 __block 存储的类型,查看 “The __block Storage Type.”
The __block Storage Type
You can specify that an imported variable be mutable—that is, read-write— by applying the __block storage type modifier. __block storage is similar to, but mutually exclusive of, the register, auto, and static storage types for local variables.
你可以指定引入的对象可以被修改,那就是,可读可写。通过给这个变量修饰 __block 存储修改类型。__block 存储与 register ,auto,static 存储方式互斥(对于一个别修饰的变量)。
__block variables live in storage that is shared between the lexical scope of the variable and all blocks and block copies declared or created within the variable’s lexical scope. Thus, the storage will survive the destruction of the stack frame if any copies of the blocks declared within the frame survive beyond the end of the frame (for example, by being enqueued somewhere for later execution). Multiple blocks in a given lexical scope can simultaneously use a shared variable.
__block 变量在一个容器中存活,可以被变量的上下文共享,可以被所有 block 共享,可以被 copy 修饰过的 block 共享,以及在 block 块中创建的对象共享。也就是说,如果有任何 copy 出来的 block 用了这个变量,它会一直存活于堆区当中。
As an optimization, block storage starts out on the stack—just like blocks themselves do. If the block is copied using Block_copy (or in Objective-C when the block is sent a copy), variables are copied to the heap. Thus, the address of a __block variable can change over time.
作为一个优化,block 存储开始与堆区,就像 blocks 他们自己做的那样子。如果这个 block 被 copy 了(或者在 OC 当中 block 接收到了 copy 消息)。变量就会被复制到栈区去。也就是说,这个变量可以一直被修改了。
There are two further restrictions on __block variables: they cannot be variable length arrays, and cannot be structures that contain C99 variable-length arrays.
对于 __block 变量有着两点限制:他们不能用于可变长度的数组,也不能包括C99中可变长度数组的结构体。
The following example illustrates use of a __block variable:
以下例子描述了怎么使用 __block 变量:
__block int x = 123; // x lives in block storage |
void (^printXAndY)(int) = ^(int y) {
|
x = x + y; |
printf("%d %d\n", x, y);
|
}; |
printXAndY(456); // prints: 579 456 |
// x is now 579 |
The following example shows the interaction of blocks with several types of variables:
以下例子显示了 blocks 如何与不同类型的变量交互:
extern NSInteger CounterGlobal; |
static NSInteger CounterStatic; |
{
|
NSInteger localCounter = 42; |
__block char localCharacter; |
void (^aBlock)(void) = ^(void) {
|
++CounterGlobal; |
++CounterStatic; |
CounterGlobal = localCounter; // localCounter fixed at block creation |
localCharacter = 'a'; // sets localCharacter in enclosing scope |
}; |
++localCounter; // unseen by the block |
localCharacter = 'b'; |
aBlock(); // execute the block |
// localCharacter now 'a' |
} |
Object and Block Variables
Blocks provide support for Objective-C and C++ objects, and other blocks, as variables.
Blocks 对 OC 以及 C++ 对象提供支持,以及其他种类的 block 最为变量。
Objective-C Objects
When a block is copied, it creates strong references to object variables used within the block. If you use a block within the implementation of a method:
当一个 block copy了,它会对每一个出现在 block 中的变量创建一个强引用。如果你在一个方法的实现中使用了 block:
If you access an instance variable by reference, a strong reference is made to
self; 如果你引用了一个实例变量,这会创建一个强引用指向 selfIf you access an instance variable by value, a strong reference is made to the variable. 如果你引用了一个实例变量的值,这回创建一个对这个变量的强引用
The following examples illustrate the two different situations:
以下例子描述了两种不同的情形:
dispatch_async(queue, ^{
|
// instanceVariable is used by reference, a strong reference is made to self |
doSomethingWithObject(instanceVariable); |
}); |
id localVariable = instanceVariable; |
dispatch_async(queue, ^{
|
/* |
localVariable is used by value, a strong reference is made to localVariable |
(and not to self). |
*/ |
doSomethingWithObject(localVariable); |
}); |
To override this behavior for a particular object variable, you can mark it with the __block storage type modifier.
为了重写这种表现形式,你可以给变量标记上 __block 存储方式。
Blocks
When you copy a block, any references to other blocks from within that block are copied if necessary—an entire tree may be copied (from the top). If you have block variables and you reference a block from within the block, that block will be copied.
当你 copy 了一个 block,任何引用到其他的 block 都会被 copy。并且会建立一个树形结构。如果你有 block 变量,并且在里面的 block 中引用了这个 block,那个 block 就会被copy。
[翻译] Blocks and Variables的更多相关文章
- Blocks and Variables
Blocks and Variables https://developer.apple.com/library/ios/documentation/cocoa/conceptual/Blocks/A ...
- Getting Started with Blocks
本文来源为:developer.apple.com,仅仅是博主练习排版所用. Getting Started with Blocks The following sections help you t ...
- block的语法
主要内容: 1. 开始使用block(Getting Started with Blocks) 2. block概念综述(Conceptual Overview) 3. 声明和创建block(Decl ...
- 最详细的block底层
主要讲述的要点: block 干什么用的 block 语法 block 底层实现 block 变量捕捉 block 的种类.在存储空间中的存储位置 block 循环引用 __block 在ARC 中 ...
- [转]50 Shades of Go: Traps, Gotchas, and Common Mistakes for New Golang Devs
http://devs.cloudimmunity.com/gotchas-and-common-mistakes-in-go-golang/ 50 Shades of Go: Traps, Gotc ...
- (译)IOS block编程指南 2 block开始
Getting Started with Blocks(开始block) The following sections help you to get started with blocks usin ...
- (译)IOS block编程指南 1 介绍
Introduction(介绍) Block objects are a C-level syntactic and runtime feature. They are similar to stan ...
- VSX(翻译)Moving Code Blocks Among Code Regions using VS 2010 Extensions
Moving Code Blocks Among Code Regions using VS 2010 Extensions (翻译)使用VS 2010 扩展性将代码块移至Region区域中 Down ...
- (翻译) How variables are allocated memory in Javascript? | scope chain | lexicial scope
总结: 阅读下面文章需要15分钟 提问者的问题是JavaScript中内存是怎么分配的,在介绍的过程作者涉及计到了JS中 Scope Chain和调用函数call生成lexicial environm ...
随机推荐
- STL中stack/queue/map以及Boost unordered_map 的使用方法
一.stackstack 模板类的定义在<stack>头文件中.stack 模板类需要两个模板参数,一个是元素类型,一个容器类型,但只有元素类型是必要的,在不指定容器类型时,默认的容器类型 ...
- DNS之XX记录
DNS服务器里有两个比较重要的记录.一个叫SOA记录(起始授权机构) 一个叫NS(Name Server)记录(域名服务器)关于这两个记录,很多文章都有解释,但是很多人还是很糊涂.我现在通俗的解释一下 ...
- JavaWeb知识回顾-servlet简介。
现在公司主要用jsp+servlet这种原生的开发方式,用的是uap的开发平台,所以趁着这个时候把有关javaweb的知识回顾一下. 首先是从servlet开始. 一.什么是Servlet?(是一些理 ...
- 【转】servlet/filter/listener/interceptor区别与联系
原文:https://www.cnblogs.com/doit8791/p/4209442.html 一.概念: 1.servlet:servlet是一种运行服务器端的java应用程序,具有独立于平台 ...
- electron写俄罗斯方块游戏(Tetris)
背景 在折腾ES6,突然想起大学时用c语言写过俄罗斯方块,本项目中主要是利用ES6的Class特性进行面向对象编程.项目采用node.js v6.2.0 + electron v1.1.0 进行桌面开 ...
- 用LR录制文件下载并随机产生文件名
用LR录制文件下载并随机产生文件名 {H.IY:X.Tn0 8h&~-D|6fV0Action()51Testing软件测试网GE$nV}s,R{51Testing软件测试网 }9sUS'q ...
- 20169211《Linux内核原理与分析》第二周作业
<linux内核分析>实验一实验报告 <linux内核设计与实现>第1.2.18章学习总结 一.<linux内核分析>实验一实验报告 在进行实验楼操作 ...
- vue-router在IE11中页面不跳转
情景: IE11浏览器中,在进行正常页面跳转操作后(页面A跳转到页面B),点击浏览器的左上角的‘后退’按钮,点击后,可以看到url地址已经发生了变化(url由页面B变为页面A),hash值也已经是上一 ...
- C# 消除累计误差的倒计时
使用 C# 中自带的各种 timer 计时,都会有累计误差,以下代码实现了一种消除累计误差的方法,使得每次计时的误差,空值在 100 ms 以内(可以通过修改代码提升精度.) 对于精度要求在秒级别的简 ...
- Lambda演算(一)大道至简
从选择信息专业开始到回炉读书为止,四舍五入码了八年代码.对于计算机科学的认知仅限于: 1)使用不同语言实现特定功能 2)实现不同算法以增进系统性能 3)搭建不同架构进行组织管理 但从未思考一些本质 ...