刚才在研究cocos2d-x源码时,遇到这么几行代码:
void AutoreleasePool::clear()
{
std::vector<Ref*> releasings;
releasings.swap(_managedObjectArray);
for (const auto &obj : releasings)
{
obj->release();
}
}
AutoreleasePool是一个用来托管内存的对象池,_managedObjectArray是一个std::vector<Ref*>类型的成员,用来保存所有管理的对象,这几行代码要做的事情就是:遍历所有对象,依次调用他们的release()方法,最后清空这个vector。
但是注意到这两句:
std::vector<Ref*> releasings;
releasings.swap(_managedObjectArray);
把一个默认的临时对象和原有的成员进行了swap,然后对交换后的临时对象进行遍历。这看起来好像是有点多余?为什么不直接遍历_managedObjectArray,然后再调用其clear()方法呢?
《Effective STL》第17条:从vector中删除元素缩减了该vector的大小(size),但是并没有减小它的容量(capacity)。
了解STL的同学都知道size和capacity的区别,那么这里的swap调用就能清楚作者意图了:遍历完vector后还要释放其所占的内存,简单地调用clear方法并不能解决问题。
swap方法的原理是交换两个vector的内部指针以达到“交换整个容器”的效果,所以在和默认的临时变量swap后,成员变量_managedObjectArray确实是个空的容器(包括内存),
临时变量在函数结束时析构,而vector正是在其析构函数中释放内存的,所以在函数结束时,所有多余的内存都被释放,一切安好!
同学们记住了,这样的技巧可以用来清空一个vector的内存:
vector<T>().swap(_vectorToBeReleased);
其效果等价于(注意花括号):
{
vector<T> temp;
temp.swap(_vectorToBeReleased);
}
该技巧同样适用于std::string。