Blocks 笔记


三种标准类型的变量,就像你在函数里面引用那样:
全局变量,包括静态局部变量。
全局函数(在技术上而言这不是变量)。
封闭范围内的局部变量和参数。
Blocks 同样支持其他两种类型的变量:
1.在函数级别是__block变量。这些在block里面是可变的(和封闭范围),并任何引
用 block 的都被保存一份副本到堆里面。
2.引入const。
3.最后,在实现方法里面,blocks也许会引用Objective-C的实例变量。参阅“对象
和 Block 变量”部分。
在 block 里面使用变量遵循以下规则:
1.全局变量可访问,包括在相同作用域范围内的静态变量。
2.传递给block的参数可访问(和函数的参数一样)。
3.程序里面属于同一作用域范围的堆(非静态的)变量作为const变量(即只读)。
它们的值在程序里面的 block 表达式内使用。在嵌套 block 里面,该值在最近的
封闭范围内被捕获。
4.属于同一作用域范围内并被__block存储修饰符标识的变量作为引用传递因此是
可变的。
5.属于同一作用域范围内block的变量,就和函数的局部变量操作一样。
每次调用 block 都提供了变量的一个拷贝。这些变量可以作为 const 来使用,或在 block 封闭范围内作为引用变量。
__block存储类型
你可以指定引入一个变量为可更改的,即读-写的,通过应用__block 存储类型修
饰符。局部变量的__block 的存储和 register、auto、static 等存储类型相似,但它们之
间不兼容。
作为一种优化,block存储在栈上面,就像blocks本身一样。如果使用Block_copy 拷贝了
block 的一个副本(或者在 Objective-C 里面给 block 发送了一条 copy 消息),
变量会被拷贝到堆上面。所以一个__block 变量的地址可以随时间推移而被更改。
Objective-C对象
在引用计数的环境里面,默认情况下当你在 block 里面引用一个 Objective-C 对象的时
候,该对象会被 retain。当你简单的引用了一个对象的实例变量时,它同样被 retain。
但是被__block 存储类型修饰符标记的对象变量不会被 retain. 注意:在垃圾回收机制里面,
如果你同时使用__weak 和__block 来标识一个变量,那么该 block 将不会保证它是一直是有
效的。

如果你在实现方法的时候使用了 block,对象的内存管理规则更微妙:
如果你通过引用来访问一个实例变量,self 会被 retain。
如果你通过值来访问一个实例变量,那么变量会被 retain。

如果你拥有__block存储的类,它本来是一个基于栈的C++对象,那么通常会使用 copy 的构造函数
如果你在 block 里面使用任何其他 C++基于栈的对象,它必须包含一个 const copy 的构造函数。
该C++对象使用该构造函数来拷贝。
当你拷贝一个 block 时,任何在该 block 里面对其他 blocks 的引用都会在需要的 时候被
拷贝,即拷贝整个目录树(从顶部开始)。如果你有 block 变量并在该 block 里 面引用其他的
block,那么那个其他的 block 会被拷贝一份。
当你拷贝一个基于栈的 block 时,你会获得一个新的 block。但是如果你拷贝一个 基于堆的
block,你只是简单的递增了该 block 的引用数,并把原始的 block 作为函数 或方法的返回值。

static、__blocks、extern修饰的的变量是可以在blocks中修改值的,其他只能被访问。 每一个引入blocks的变量都会被拷贝一份,加上const修饰。可修改的拷贝的是引用地址,不可修改的拷贝的是值。

posted @ 2013-05-27 14:10  jiangmingz  阅读(146)  评论(0编辑  收藏  举报