Cocos2d-x的内存管理(2)

2015年03月22日 16:21 0 点赞 0 评论 更新于 2025-11-21 18:10

Vector

Vector 是 Cocos2d-x 3.x 系列之后引入的新数据结构,它综合了 std::vector 的诸多函数,能便捷地进行各类数据操作,同时融入了 Cocos2d-x 的内存管理机制。

与普通类型(如 sprite)不同,Vector 是用于存储一组数据的容器,从其名称便可推断,它需要管理一大块内存。例如,可将 5 个 sprite 对象存入一个 Vector 中,此时 Vector 不仅要对这 5 个 sprite 进行内存管理,还需具备高效地对这些数据进行插入、删除、搜索等操作的能力。

为实现对存储元素的内存管理,Vector 采用了 Cocos2d-X 的引用计数和智能指针理念。具体而言,Vector 本身是局部变量,其内存分配在栈上,不占用堆内存,因此它的生命周期受作用域控制。在 Vector 的析构函数中,会自动进行内存释放操作。此外,传入 Vector 的变量必须是 Ref 的子类,这样才能使用引用计数的 retainrelease 函数。在对 Vector 进行操作时,会根据不同操作进行相应的内存管理:

  • 在执行 copypushBackinsertreplace 操作时,会对元素调用 retain 函数,增加元素的引用计数。
  • 在执行 popbackeraseclearreplace 操作时,会对元素调用 release 函数,减少元素的引用计数。
  • 在执行 swapmove 操作时,不会对元素进行内存管理。

为了方便有效地操作数据,Vector 基于 std::vector 进行了封装,它不仅提供了 std::vector 的常用方法,如 beginendcapacitysizeemptymax_sizegetIndexfrontbackshrinkToFit 等,还自定义了一些方法,如 replaceswapfind 等。

Map

Map 与 Vector 类似,它包装了 std::unordered_mapstd::map,同样融入了 Cocos2d-x 的内存管理机制。

unordered_map 会将键(key)转换为哈希值(hash),并按照哈希值的顺序存储元素,而非按照键或值的顺序。在进行搜索操作时,会先将键转换为哈希值,然后进行查找,其算法复杂度最快为 O(1),最慢为 O(n)。unordered_map 的哈希算法基于一个固定值 buckets 进行计算,因此在创建 Map 时,需要设定一个 buckets 值,该值类似于 reservecapacity。如果 Map 中存储的元素数量超过 buckets,就需要重新计算哈希值。所以,需要根据元素插入的频繁程度和数量来权衡,确定创建 Map 时 reservecapacity。另外,如果键为 int 类型,会直接使用该键作为哈希值。

在内存管理方面,Map 的值(value)相当于 Vector 的元素。在内存管理过程中,Vector 会对元素进行 retainrelease 操作,而 Map 则会对值(即 iter->second)进行同样的操作。

Value

Vector 和 Map 都属于容器类型,而 Value 则是一个包装体,它可以包装 IntFloatVector 等所有数据结构。所有数据都可以定义为 Value 类型,然后通过 Value 提供的方法进行数据类型转换,并通过 Value 的析构函数进行内存管理。

Value 的构造函数接受一个参数,该参数用于为 Value 赋值,并确定其数据类型。例如,如果传入的参数为 int 类型,那么 Value 就是 int 类型的数据;如果传入的参数为 std::vector,则会在堆上分配一块内存来存储该 vector,并进行赋值。

由于 Value 通常是局部对象,在其生命周期结束时,会调用析构函数,释放之前分配的内存(如 vector)。在进行赋值操作时,如果 Value 本身的数据类型与新参数的数据类型不匹配,例如之前存储的是 std::vector,新参数为 std::unordered_map,则会先释放之前分配的内存,再重新分配一块新的内存。如果是 move 操作,只需清空原有的数据,然后将参数的数据移动过来,并将参数的类型设置为 none。在进行数据类型转换时,如果可以转换则进行转换,否则将转换结果设为 0。

作者信息

menghao

menghao

共发布了 3994 篇文章