Block(五)heap-stack-memory


操作系统iOS 中应用程序使用的计算机内存不是统一分配空间,运行代码使用的空间在三个不同的内存区域,分成三个段:“text segment ““stack segment ”“heap segment ”

使用ARC(自动引用计数),blocks 语法使用起来让工作变得很容易,特别是在执行异步任务程序的时候。这个地方介绍几个需要注意和理解的概念,这样有助于理解blocks是怎么工作的。



内存:

1. Stack(栈内存):编译器读写变量最快速的方式。每一个线程有一个属于自己的栈。线程之间是通过堆(heap)来共享信息的。当进入一个代码块的时候(使用{Objecitve-C code}),编译器会为其栈中的任务分配一块内存,当代码执行完毕的时候(函数返回或者进入一个闭包),编译器会释放占中的内存空间,会给父代码先前所在的位置返回一个栈指针。因为执行完了就会立即释放并返回:所以栈中的对象是没法引用计数保留的,无论怎样其中的对象都会在代码执行完的时候被释放掉。


2. Heap(堆内存):对于每一个应用程序来说,它都是唯一并且为所有线程共享。在堆中的对象结构会一直存在,除非进行手动释放或者使用ARC 的自动施法机制。对比栈内存,堆内存的读取熟读要慢,它的主要特点有:它可以根据需求动态的请求内存空间(栈内存的情况下如果内存溢出就会出现app崩溃或者栈溢出异常),在堆内存中对对象进行删除不会影响到其它的变量(在栈中这是不可能的,因为栈中的pushpop事件是有一个指定顺序的)。


3. Blocks(块语法):blocksObjective-C中唯一的默认在栈内存中的对象。因为编译器总是优先在栈中开辟分配事务(因为这样会更快),不过前提是必须知道准确的开辟空间的大小。只有简单变量(plain values 譬如有指针)可以在栈中分配内存。blocks是有确定大小的。一旦创建了一个block就不能够将它变更,blocks在整个执行过程中是产量形式,他们要执行的快,所以是代码片段的形式存在,所以更时候与存在于栈内存的形式。



----

*   记住blocks一旦创建就不会被释放掉,除非我们手动操作了。我们可以将一个block移到别的代码中吗?答案是可以的,需要通过copy操作。任何时候对block进行的copy操作都会将block拷贝一份并存在于堆内存中。所以,也需要对这份堆内存中的block的内存管理进行负责(如果是ARCit会像处理其他的属性一样自动完成内存管理)


*   注意:引用block如果使用retain 而不是copy,那么只有在block存在于堆中的时候有效,如果block存在于栈中,那么block是没法被应用计数管理的,无论使用了多少个retain,执行完毕之后block依旧会被释放。所以最好还是使用copy吧。对一个block多次使用copy其实并不会创建多个拷贝对象,它会变成对堆内存中的block对象进行引用计数的+1. 也就是说一旦block进入了堆内存,就和其它的OC对象一样,适合于OC的引用计数内存管理机制了。


*   block内存管理的上的两个原则:a.如果是创建了一个block使用到其它的类中(最常见的情况),那么不需要去copy它,这是消息接收者的任务,receiver需要在使用完之后去释放它; b.如果是在自己当前类中创建或者使用了一个block,并且在当前内的不同代码块中执行了block,那么需要使用到copy,并且在使用完之后将它set nil进行释放。

-----



4.  Retain Circles(引用循环,在block中使用self):

    如果self强持有引用一个block,而这个block代码中又引用到self,那么久造成了引用循环,(注意如果block是在栈内存中那么不存在这个问题,因为block绘制执行完毕之后就立即被返回释放,这里说的情况必然是block存在于堆内存中。)解决循环引用有一些策略,其中一种是在block执行完毕之后手动setting nil,但是这样block就只能执行一次之后就会再无效用了,为此使用另外一种策略:__weak MyClass * weakSelf = self;这样weakSelf就不会对引用计数加一了,不过会存在一个问题,这个用法需要保证self以及其属性保证在每次block执行的时候都是有效的(即使在其它的类中执行),否则就会get a bad access memory

    其实在ARC中,所有的这些策略都可以忽略,ARC会处理好所有,不过为了确保程序百分之百的正确规则,苹果还是建议总要严格的使用这些策略方法。



几篇不错的相关文章:


//http://mikixiyou.iteye.com/blog/1595230

//http://ios.jobbole.com/81900/

//http://www.solstice-mobile.com/blog/blocks-and-memory-management-stack-vs-heap

//http://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap



--


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值