Block的内存管理


程序运行到这时,stack空间有shared变量和captured变量。__block变量开始处于stack上的。




执行到这时,stack变量中有shared变量、captured变量和block1.但是值得注意的是:当我么直接修改stack上的captured变量时,

block1中的captured变量仍然是原来的数值10。事实上,block1中的captured变量是不能被修改的,它是从stack原有变量的一个const

拷贝,在block1中访问的captured变量是const拷贝的,也就是block1中的captured = 10,而不是原有stack上的20,当然,我们也不能修改captured变量。




Copy Block


block一开始的时候在stack上,这是为了考虑效率的原因,但是有时候是需要block的生命周期长于一开始的stack,

这时,我们就通过[copy block] 来将block复制到heap。




当程序执行完 block2 = [block1 copy];__block 类型变量shared被复制到heap中,很显然,shared变量需要,shared变量

需要被block和block2共享(当然还有stack也要共享),而block2也被移动到heap中,很可能生命周期会长于stack,所以,

shared也被复制到heap中,而block2中的caputured也被复制到heap中。





当程序执行完block3= [block2 copy];时,我们看到的是block2和block3指向的是同一片内存空间,事实上,block的数据结构中,

保存了引用计数,而对于copy到heap中的block 再copy时,行为同普通的对象retain一样,引用计数+1.

但是如果执行【block retain】会如何?实际上什么都没有发生,至少在现在runtime版本下。因为retain中,不仅有引用计数+1在,而且retain的返回值,必须同返回调用对象的地址一样。而block的地址是可能变化的(stack或heap),所以在这里的retain行为是被忽略的。



如果调用[block2 release];[block3 release];heap中的block变量先于stack被销毁。heap中的block2和block3由于引用计数为0而被销毁,而__block变量shared则还在heap中,因为stack还要使用,block1也要使用。




如果当heap中block变量晚于stack时,显然stack被清除,function中也啥也没了。



最后,当block2和block3都被release之后,则恢复到最初状态。


Block存放的位置:

没有copy过的block存放在栈中,copy后的block存放在堆中。

static int(^maxIntBlock)(int ,int) = ^(int a,int b);这种情况下block位于全局区,即使是复制过后依旧在全局区中。


block引用的变量在哪?

1.全局的变量存储位置与block无关:eg:static int gVar = 0;  注意:static 变量是不允许添加 __block标记的


2.看一段代码

void foo()

{

__block int i = 1025; //此时位于栈上

int j = 1;//位于栈上

void (^blk)(void);

blk = ^{printf(@"%d,%d",i,j)}; //此时block和i,j都是位于栈上。

blk();

int (^blkInHeap)(int,int) = Block_copy(blk);//复制blk后,blk位于堆上。有__block标记的的i也会被复制一份到堆上,没有     //该标记的仍然在栈上。

}



对block调用复制,有以下几种情况:

1.对全局区的block调用copy,会返回原指针,并且这期间不处理任何东西(至少目前的内部实现是这样);

2.对栈上的block调用copy,会返回复制到堆上的block的指针,同时,所有__block变量都会被复制至堆一份(多次拷贝,只会生成一份)。

3.对已经位于heap上的block,再次调用copy,只会增加block的引用计数。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值