浅谈内存开辟问题和Block内存问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈内存开辟问题和Block内存问题相关的知识,希望对你有一定的参考价值。

我们知道,内存分为栈,堆,块。

栈中的内存由系统自己释放,堆是存对象初始化的地方,块是CPU与内存连接的缓冲器,运行速度比内存快,比CPU慢。

例如,我们NSMutableArray *array = [NSMutableArrar new];

NSMutableArray *array就在栈中,NSMutableArray类型的指针。[NSMutableArray new]开辟的内存在堆中,我们可以理解为

NSMutableArray *array --->[NSMutableArrar new];

栈中的指针指向堆中的对象。

我们用static或者const关键字定义常量,一般在内存块中开辟内存空间。在块中开辟内存空间的对象读写速度最快,但是我们要注意,块的内存很小。

 

block代码是在块中执行的,所以它的运行速度要比delegate等效率高。但是使用block容易造成内存泄露。

原因在网上找到了:http://www.cnblogs.com/hanjun/p/3767394.html

  • NSGlobalBlock:类似函数,位于text段;我们可以通过是否引用外部变量识别,未引用外部变量即为NSGlobalBlock,可以当做函数使用。
  • NSStackBlock:位于栈内存,函数返回后Block将无效;
  • NSMallocBlock:位于堆内存,NSMallocBlock只需要对NSStackBlock进行copy操作就可以获取。

 

  • Block_copy与copy等效,Block_release与release等效;
  • 对Block不管是retain、copy、release都不会改变引用计数retainCount,retainCount始终是1;
  • NSGlobalBlock:retain、copy、release操作都无效;
  • NSStackBlock:retain、release操作无效,必须注意的是,NSStackBlock在函数返回后,Block内存将被回收。即使retain也没用。容易犯的错误是[[mutableAarry addObject:stackBlock],(补:在arc中不用担心此问题,因为arc中会默认将实例化的block拷贝到堆上)在函数出栈后,从mutableAarry中取到的stackBlock已经被回收,变成了野指针。正确的做法是先将stackBlock copy到堆上,然后加入数组:[mutableAarry addObject:[[stackBlock copy] autorelease]]。支持copy,copy之后生成新的NSMallocBlock类型对象。
  • NSMallocBlock支持retain、release,虽然retainCount始终是1,但内存管理器中仍然会增加、减少计数。copy之后不会生成新的对象,只是增加了一次引用,类似retain;
  • 尽量不要对Block使用retain操作。

以上是关于浅谈内存开辟问题和Block内存问题的主要内容,如果未能解决你的问题,请参考以下文章

浅谈C语言内存

浅谈js中的深拷贝和浅拷贝

用C语言分配开辟内存问题

从内存层次浅谈动态与静态

浅谈HashMap实现原理

JS浅谈原始值与引用值操作