1. 总结

Sprite和SpriteFrame和Texture2D关系紧密,三个类都继承了Ref类。精灵有成员精灵帧和纹理,精灵帧有成员纹理。精灵帧和纹理被精灵帧引用时,引用计数增加,不再被引用时,引用计数减少。纹理被精灵帧引用时也同理。

一个纹理可以被多个精灵帧、精灵引用,一个精灵帧可以被多个精灵引用。

为什么纹理缓存容器不用CC的包装类Map

纹理缓存和精灵帧缓存不同,纹理缓存的容器不是包装类,即向容器中增加和删除纹理不会改变纹理的引用计数。

纹理除异步之外不执行autorelease(),精灵和精灵帧在create()执行autorelease()。

纹理不使用autorelease(),确保了不被引用的纹理不会在每帧结束后被自动release(),而是在需要释放的时候调用remove等方法手动执行release(),确保对内存中的纹理手动释放。也是让暂时没用但以后要用的纹理留在内存中,避免以后重新新建该texture。

纹理缓存的addImage方法中,将新纹理加入到容器时,不会增加引用计数。因为在精灵的create方法中,addImage方法执行后执行setTexture方法,使得引用计数加1。

2. Sprite

Sprite成员变量包括:

Texture2D*       _texture;              /// Texture2D object that is used to render the sprite
SpriteFrame* _spriteFrame;

create(...)

我们执行Sprite类的createxxx(...)等方法,都会新建Sprite对象,对成员变量_texture和_spriteFrame等设置默认值,再调用autorelease()方法,将Sprite对象交给内存管理池自动管理。

setTexture(Texture2D *texture)

在给精灵设置纹理时,若纹理指针为空指针,则执行以下方法尝试从纹理缓存中获取Key为CC_2x2_WHITE_IMAGE_KEY的纹理的指针:

_director->getTextureCache()->getTextureForKey(CC_2x2_WHITE_IMAGE_KEY);

若空白纹理不存在于纹理内存,则新建Image类对象从而新建空白纹理。Image对象继承Ref类,新建时默认引用计数=1,在空白纹理的指针赋给纹理指针后,Image对象执行release()方法,从内存中删除。

此时,若参数纹理指针不等于Sprite本身的纹理指针时,参数纹理retain(),本身纹理release(),参数纹理作为本身纹理指针。

setSpriteFrame(SpriteFrame *spriteFrame)

在给精灵设置精灵帧时,若参数精灵帧指针不等于本身精灵帧指针,对本身精灵帧release(),参数精灵帧retain(),参数精灵帧作为本身精灵帧。

~Sprite()

Sprite对象析构时,会对成员_spriteFrame和_texture执行release()。

addChild(...) removeChild(...) 不再赘述。

3. SpriteFrame SpriteFrameCache

精灵帧缓存的容器_spriteFrames是Map<std::string, SpriteFrame*>类型,添加精灵帧和删除都封装了retain()和release()方法

SpriteFrame::create(const std::string& filename, const Rect& rect)

创建精灵帧时,要将精灵帧执行autorelease()方法,放入内存管理池。

~SpriteFrame()

析构时,对精灵帧成员_texture执行release()

SpriteFrame::setTexture(Texture2D * texture)

对精灵帧的成员_texture设置新的时,原先纹理执行release(),新纹理执行retain()。

SpriteFrame::initWithTexture(Texture2D* texture, ...)

用纹理对精灵帧初始化,纹理执行retain()

SpriteFrameCache::removeSpriteFrames()

SpriteFrameCache::removeSpriteFrameByName(const std::string& name)

SpriteFrameCache::addSpriteFramesWithDictionary(ValueMap& dictionary, Texture2D* texture)

删除是对Map容器执行clear(),会对容器中所有精灵帧执行release(),再清空map。删除特定精灵帧,对容器中精灵帧release()。增加特定精灵帧,对容器中精灵帧retain()。

SpriteFrameCache::destroyInstance()

精灵帧缓存是单例,销毁时执行release()。

4. Texture2D TextureCache

纹理缓存是对纹理的缓存,纹理指针以map形式被保存在容器_textures中,容器类型std::unordered_map<std::string, Texture2D*>。

在用Image对象创建纹理时,新建的Image对象使用完后要调用release()及时从内存中删除。

~TextureCache()

析构时对容器中所有纹理执行release()。

addImage(const std::string &path)

在添加纹理到纹理缓存中,如果纹理不存在于缓存,且又新建该纹理失败,就把刚刚new的texture对象release()。

image = new (std::nothrow) Image();
texture = new (std::nothrow) Texture2D();
if (texture && texture->initWithImage(image))
{
// ...
}
else
{
// ...
CC_SAFE_RELEASE(texture);
texture = nullptr;
}
CC_SAFE_RELEASE(image);

removeAllTextures()

删除缓存容器中所有纹理,实际上是对这些纹理执行release()。

removeUnusedTextures()

删除没有使用的纹理,实际是对引用计数为1的纹理-1。

removeTexture(Texture2D* texture) removeTextureForKey(...)

it->second->release();
it = _textures.erase(it);

Cocos2d-x 学习笔记(7) 内存管理 Sprite SpriteFrame Texture2D的更多相关文章

  1. linux kernel学习笔记-5内存管理_转

    void * kmalloc(size_t size, gfp_t gfp_mask); kmalloc()第一个参数是要分配的块的大小,第一个参数为分配标志,用于控制kmalloc()的行为. km ...

  2. XV6学习笔记(2) :内存管理

    XV6学习笔记(2) :内存管理 在学习笔记1中,完成了对于pc启动和加载的过程.目前已经可以开始在c语言代码中运行了,而当前已经开启了分页模式,不过是两个4mb的大的内存页,而没有开启小的内存页.接 ...

  3. Cocos2D-X2.2.3学习笔记3(内存管理)

    本章节介绍例如以下: 1.C/C++内存管理机制 2.引用计数机制 3.自己主动释放机制 1.C/C++内存管理机制 相信仅仅要懂oop的都知道NEW这个keyword吧,这个通俗点说事实上就是创建对 ...

  4. COCOS学习笔记--Cocod2dx内存管理(三)-Coco2d-x内存执行原理

    通过上两篇博客.我们对Cocos引用计数和Ref类.PoolManager类以及AutoreleasePool类已有所了解,那么接下来就通过举栗子来进一步看看Coco2d-x内存执行原理是如何的. / ...

  5. 嵌入式linux学习笔记1—内存管理MMU之虚拟地址到物理地址的转化

    一.内存管理基本知识 1.S3C2440最多会用到两级页表:以段的方式进行转换时只用到一级页表,以页的方式进行转换时用到两级页表.页的大小有三种:大页(64KB),小页(4KB),极小页(1KB).条 ...

  6. Linux内核学习笔记——内核内存管理方式

    一 页 内核把物理页作为内存管理的基本单位:内存管理单元(MMU)把虚拟地址转换为物理 地址,通常以页为单位进行处理.MMU以页大小为单位来管理系统中的也表. 32位系统:页大小4KB 64位系统:页 ...

  7. ios学习笔记之内存管理

    一,内存管理类型定义      1,基本类型  任何C的类型,eg:      int,short,char,long,long long,struct,enum,union等属于基本类型或结构体   ...

  8. arm-linux学习笔记3-linux内存管理与文件操作

    配置好linux系统之后需要vim配置一下,有助于我们的编程,主要的配置如下 在/etc/vim/vimrc文件中 "显示行号 set number "自动缩进 set autoi ...

  9. 《C#高级编程》学习笔记----c#内存管理--栈VS堆

    本文转载自Netprawn,原文英文版地址 尽管在.net framework中我们不太需要关注内存管理和垃圾回收这方面的问题,但是出于提高我们应用程序性能的目的,在我们的脑子里还是需要有这方面的意识 ...

随机推荐

  1. ubuntu 12.04下访问windows共享文件夹

    ubuntu 12.04LTS已经不支持smbfs文件系统,所以不能用mount -smbfs 来映射windows共享文件夹. 常见有两种方法 1.terminal下 mount //192.168 ...

  2. java获取电脑mac物理地址

    import java.net.InetAddress;import java.net.NetworkInterface;import java.net.SocketException;import ...

  3. centos7搭建squid

    squid在做爬虫代理时候,我们只需要做到一个squid代理,然后对其他代理做转发轮询,如何使用squid做代理并自动转发轮询? 加上这行代码: cache_peer 120.xx.xx.32 par ...

  4. [VB.NET Tips]Select Case语句拾遗

    正常的Select 语句如下: Dim status As Integer = 5 Select Case status Case 0 Console.WriteLine("状态是:0&qu ...

  5. 搭建大数据开发环境-Hadoop篇

    前期准备 操作系统 hadoop目前对linux操作系统支持是最好的,可以部署2000个节点的服务器集群:在hadoop2.2以后,开始支持windows操作系统,但是兼容性没有linux好.因此,建 ...

  6. Postman 之 HTTP Multipart/form-data 调试

    无论是前端,还是后端开发,HTTP 接口的使用率实在是太高了.开发好了特定的 HTTP 接口,没有一个好的测试工具,怎么可以呢? 而 Postman 就是一款好用的爱不释手的测试工具,谁用谁说爽. 接 ...

  7. Scrapy项目 - 数据简析 - 实现豆瓣 Top250 电影信息爬取的爬虫设计

    一.数据分析截图(weka数据分析截图 ) 本例实验,使用Weka 3.7对豆瓣电影网页上所罗列的上映电影信息,如:标题.主要信息(年份.国家.类型)和评分等的信息进行数据分析,Weka 3.7数据分 ...

  8. 利用百度云接口实现车牌识别·python

    一个小需求---实现车牌识别. 目前有两个想法 1. 调云在线的接口或者使用SDK做开发(配置环境和变异第三方库麻烦,当然使用python可以避免这些问题) 2. 自己实现车牌识别算法(复杂) 一开始 ...

  9. 搭建Nodejs环境 创建Express应用

    1. Nodejs Nodejs是一种服务器端js脚本运行环境: Nodejs框架是基于V8的引擎,是目前速度最快的Javascript引擎 2. Express开发框架 极简的web框架,完全是由路 ...

  10. uC/OS-III 时钟节拍(一)

    时钟节拍就是操作系统的时基,操作系统要实现时间上的管理,必须依赖于时基(时基即时间基准,操作系统的基准时钟). uC/OS-III时钟节拍的实现过程 时钟节拍就是系统以固定的频率产生中断(时基中断), ...