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. b146: NOIP2004 1.不高兴的津津

    题目: 津津上初中了.妈妈认为津津应该更加用功学习,所以津津除了上学之外,还要参加妈妈为她报名的各科复习班.另外每周妈妈还会送她去学习朗诵.舞蹈和钢琴.但是津津如果一天上课超过八个小时就会不高兴,而且 ...

  2. StringBulider类

    StringBulider类创建的字符串同样可以对字符串进行修改: public class StringBuliderDemo { public static void main(String[] ...

  3. Comet OJ - Contest #11 题解&赛后总结

    Solution of Comet OJ - Contest #11 A.eon -Problem designed by Starria- 在模 10 意义下,答案变为最大数的最低位(即原数数位的最 ...

  4. PTA A1013

    第七天 A1013 Battle Over Cities (25 分) 题目内容 It is vitally important to have all the cities connected by ...

  5. 数据结构慕课PTA 05-树9 Huffman Codes

    题目内容 In 1953, David A. Huffman published his paper "A Method for the Construction of Minimum-Re ...

  6. 百度脑图-离线版(支持Linux、Mac、Win)

    免费好用的思维导图软件(在线版) 离线版:桌面版脑图是基于百度脑图的本地化版本,帮助你在没有互联网环境的情况下,依然可以使用脑图工具. 百度脑图帮助你进行思维导图,可以运用于学习.写作.沟通.演讲.管 ...

  7. go语言-最大32位数反转

    package main import ( "fmt" "strconv" ) func fanzhuang32(number int) string { fu ...

  8. KeyValue对RDDs

    创建KeyValue对RDDs 使用函数map,返回keyvalue对 例如,包含数行数据的RDD,那每行的第一个单词作为keys. sparl.txt中的内容如下: hello ! hello wo ...

  9. Django+MySQL Dashboard 网页端数据库可视化

    1. Overview Python+MySQL+Django, 有些数据托管在 MySQL 的数据库,然后我们希望进行可视化,通过 web 的方式对数据库的信息去进行展示/检索/维护/.. 这个项目 ...

  10. 基于操作系统的Linux网络参数的配置

    一.实验目的 1.掌握Linux下网络参数的查看方法并理解网络参数的含义. 2.掌握Linux下网络参数的配置 二.实验内容 1.查看当前网络配置的参数. 2.在Linux主机中将网络参数按以下要求设 ...