C++内存分配区域
(2):堆区域。从堆上分配,也叫做动态内存分配。由开发人员自己管理释放操作。程序在运行时用malloc或new来申请任意大小的内存,用free或delete来释放内存。其中malloc和free搭配,new和delete搭配。这种方法使用非常灵活,但是问题也是非常多。
(3):在静态存储区域分配。这个内存空间在程序整个运行期间都存在,内存在程序编译的时候就已经分配好了。它可以用来分配全局变量和静态变量。
动态内存分配
1.malloc和free的使用。
另外需要注意的是malloc返回的是void*,由于c++不允许void*赋值给其他指针的对象,所以在前面需要强制转换。
2.new和delete的使用。
与malloc和free不同的是,new和delete不是函数库,而是c++的运算符。new运算符能够完成创建对象的所有步骤(第一步:为对象分配内存;第二步:调用构造函数初始化对象)。new运算符的反操作是delete运算符,delete先调用析构函数,在释放内存。值得注意的是,delete释放后的对象需要赋值NULL来防止“野指针”的产生。
("野指针“的产生一种情况是,指针变量没有被初始化,所以呐,它的指向就是随机的了,它会乱指,并不是想象中的NULL。另一种情况是,指针变量被free或者delete之后,它们只是把指针所指向的那部分内存释放了,并没有把指针本身清楚,此时指针指向的就是”垃圾内存“,”野指针“是很危险的情况,所以在释放完指针之后为其赋值NULL,是防止”野指针“最好的办法。)
Ref内存管理
内存引用计数:
每个Ref对象都有一个内部计数器,这个计数器跟踪对象的引用次数,被称为”引用计数“(RC)。就是说,有一个对象被创建时,引用计数为1.为了保证对象的存在,可以调用retain函数保持对象,retain会使引用计数加1,如果不需要这个对象可以调用release函数,release使其引用计数减1,。当对象的引用计数为0时,引擎就知道不需要这个对象了,这个对象自然地也就被释放掉了。
在Ref类中相关函数由retain()、release()、autorelease()和getReferenceCount()。其中,autorelease()函数与release()函数类似,它会延后使计时器减1。getReferenceCount()函数返回当前的引用计数。
自动释放池
比如说在一个函数中new出了一个对象,然后需要返回这个对象。按照c++的规则new出一个对象之后还需要delete掉,不然每次调用这个函数都会创建一个新对象,老的对象没有释放,就会造成严重的内存泄漏。但是如果release之后,那么问题可能更加严重了,因为release之后返回的对象可能是一个野指针。
所以说,自动释放池(AutoReleasePool)真是为了解决这个问题的,它能够管理即将被释放的对象。autorelease()函数将对象放到自动释放池。但是对象的引用计数并不会立即减1,而是要等到一个消息结束之后,才会减1,如果引用计数为0,则释放此对象。
自动释放池的生命周期也是由消息循环管理的,每次为了处理新的事件,Cocos2d-x都会创建一个新的自动释放池,事件处理完成后,就会销毁这个释放池,池中的对象的引用计数都会减1。如果这个对象的引用计数为0,也就是没有被其他类或Ref对象retain,否则这个对象不会被释放,在这次销毁中”幸存“下来的,都会被转移到下一个池中继续生存。
Ref内存管理规则
(1)。在使用Node节点对象时,addChild可以保持Node节点对象,使引用计数加1。通过removeChild函数移除Node节点对象,使引用计数减1.他们都是隐式调用的,用户不需要关心它们的内存管理。
(2)。如果是_Array和_Dictionary等容器对象,通过它们的add相关函数添加元素会使引用计数加1,相反的,remove相关函数删除元素会使其引用计数减1.但是前提是_Array和_Dictionary等容器本身并没有被释放。
使用静态构造函数
Cocos2d-x将这种由create开头的静态创建对象的函数叫做”静态构造函数“。create开头的静态构造函数是采用静态工厂设计模式,工厂设计模式是一种创建模式,它能够将创建对象的细节屏蔽掉,用户不需要关心其内部的运行机理。在内存管理方面,采用这种工厂模式后,不用关心对象的retain、release和autorelease等问题。事实上,使用静态构造函数创建的Ref对象,在使用过程中一般不需要retain、release和autorelease函数。不然容易造成异常。
使用访问器
(1)CC_PROPERTY。定义一个访问器,没有提供set和get访问函数的实现。
(2)CC_SYNTHESIZE。同CC_PROPERTY,提供set和get访问函数的实现。
(3)CC_SYNTHESIZE_RETAIN。同CC_PROPERTY,提供给set和get访问函数的实现。用于Ref类型的参数。
(4)CC_PROPERTY_READONLY。定义一个只有get的访问器