2d-x深读4:CCAutoReleasePool

CCAutoReleasePool.h主要定义了两个类CCAutoReleasePoolCCPoolManager.

其实因为cocos2d-x自动管理内存的原因, 所以, 我们平时很少需要直接使用这两个类.
为了探究其中的自动管理内存的机制, 我们直接分析其代码.

总体上来讲, 内存管理这块的机制难度或许比较大. 我研究了一天, 还是有诸多疑问.
暂时先放一放, 待我功力进化后再来继续研究这块.

  • 版本:cocos2d-2.1beta3-x-2.1.0
  • 路径:cocos2d-2.1beta3-x-2.1.0/cocos2dx/cocoa/CCAutoReleasePool.h
  • 路径:cocos2d-2.1beta3-x-2.1.0/cocos2dx/cocoa/CCAutoReleasePool.cpp
CCAutoReleasePool\.hview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 声明CCAutoreleasePool类
class CC_DLL CCAutoreleasePool : public CCObject
{//注意这个m_pCurReleasePool是一个私有成员. 居然没有加标号.
CCArray* m_pManagedObjectArray;
public:
CCAutoreleasePool(void);
~CCAutoreleasePool(void);
void addObject(CCObject *pObject);
void removeObject(CCObject *pObject);
void clear();
};
class CC_DLL CCPoolManager
{//下面这三个成员变量依然是私有的.
CCArray* m_pReleasePoolStack;
CCAutoreleasePool* m_pCurReleasePool;
CCAutoreleasePool* getCurReleasePool();
public:
CCPoolManager();
~CCPoolManager();
void finalize();
void push();
void pop();
void removeObject(CCObject* pObject);
void addObject(CCObject* pObject);
static CCPoolManager* sharedPoolManager();
static void purgePoolManager();
//友元
friend class CCAutoreleasePool;
};
CCAutoReleasePool\.cppview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
static CCPoolManager* s_pPoolManager = NULL;// 用作单例模式的静态变量.
CCAutoreleasePool::CCAutoreleasePool(void)
{
m_pManagedObjectArray = new CCArray();
m_pManagedObjectArray->init();
}
CCAutoreleasePool::~CCAutoreleasePool(void)
{
CC_SAFE_DELETE(m_pManagedObjectArray);
}
void CCAutoreleasePool::addObject(CCObject* pObject)
{
m_pManagedObjectArray->addObject(pObject);
// CCAutoreleasePool是CCObject的友元类, 可以直接访问CCObject的protect成员变量.
CCAssert(pObject->m_uReference > 1, "reference count should be greater than 1");
++(pObject->m_uAutoReleaseCount);
pObject->release(); // no ref count, in this case autorelease pool added.
}
// 下面这个遍历似乎是为了应对被多次加入pool
void CCAutoreleasePool::removeObject(CCObject* pObject)
{
for (unsigned int i = 0; i < pObject->m_uAutoReleaseCount; ++i)
{
m_pManagedObjectArray->removeObject(pObject, false);
}
}
// 清空池
void CCAutoreleasePool::clear()
{
if(m_pManagedObjectArray->count() > 0)
{
//CCAutoreleasePool* pReleasePool;
#ifdef _DEBUG
int nIndex = m_pManagedObjectArray->count() - 1;
#endif
CCObject* pObj = NULL;
CCARRAY_FOREACH_REVERSE(m_pManagedObjectArray, pObj)//反序遍历
{
// 这里还是令人费解, 为何会使用break, 而不是使用continue完成遍历????
if(!pObj)
break;
--(pObj->m_uAutoReleaseCount);
//(*it)->release();
//delete (*it);
#ifdef _DEBUG
nIndex--;
#endif
}
m_pManagedObjectArray->removeAllObjects();
}
}
// CCPoolManager的单例
CCPoolManager* CCPoolManager::sharedPoolManager()
{
if (s_pPoolManager == NULL)
{
s_pPoolManager = new CCPoolManager();
}
return s_pPoolManager;
}
// 销毁当前manager
void CCPoolManager::purgePoolManager()
{
CC_SAFE_DELETE(s_pPoolManager);
}
//构造函数
CCPoolManager::CCPoolManager()
{
m_pReleasePoolStack = new CCArray();
m_pReleasePoolStack->init();
m_pCurReleasePool = 0;
}
// 析构函数
CCPoolManager::~CCPoolManager()
{
finalize();
// 这个注释也让人费解. 为什么只移除第一个, 而不是遍历????
// we only release the last autorelease pool here
m_pCurReleasePool = 0;
m_pReleasePoolStack->removeObjectAtIndex(0);
CC_SAFE_DELETE(m_pReleasePoolStack);
}
void CCPoolManager::finalize()
{
if(m_pReleasePoolStack->count() > 0)
{
//CCAutoreleasePool* pReleasePool;
CCObject* pObj = NULL;
CCARRAY_FOREACH(m_pReleasePoolStack, pObj)
{
// 这里有点令人不解, 为什么遍历还没有完成就break了???
// 或许是因为pop push的方式不会在中间产生为NULL的池.
if(!pObj)
break;
CCAutoreleasePool* pPool = (CCAutoreleasePool*)pObj;
pPool->clear();
}
}
}
//创建一个新池, 注意其中pPool的引用计数的变化.
void CCPoolManager::push()
{
CCAutoreleasePool* pPool = new CCAutoreleasePool(); //ref = 1
m_pCurReleasePool = pPool;
m_pReleasePoolStack->addObject(pPool); //ref = 2
pPool->release(); //ref = 1
}
//销毁当前池
void CCPoolManager::pop()
{
if (! m_pCurReleasePool)
{
return;
}
int nCount = m_pReleasePoolStack->count();
m_pCurReleasePool->clear();
if(nCount > 1)
{//注意这里removeObjectAtIndex会将当前池的引用技术减1, 从而销毁当前池.
m_pReleasePoolStack->removeObjectAtIndex(nCount-1);
// if(nCount > 1)
// {
// m_pCurReleasePool = m_pReleasePoolStack->objectAtIndex(nCount - 2);
// return;
// }
m_pCurReleasePool = (CCAutoreleasePool*)m_pReleasePoolStack->objectAtIndex(nCount - 2);
}
//如果没有意外, 这里会最少保留一个池不会被销毁. 但最后一个池还是会被清空..
/*m_pCurReleasePool = NULL;*/
}
// 从当前池中移除对象.
void CCPoolManager::removeObject(CCObject* pObject)
{
CCAssert(m_pCurReleasePool, "current auto release pool should not be null");
m_pCurReleasePool->removeObject(pObject);
}
//添加一个对象到当前池
void CCPoolManager::addObject(CCObject* pObject)
{
getCurReleasePool()->addObject(pObject);
}
//形成单例模式
CCAutoreleasePool* CCPoolManager::getCurReleasePool()
{
if(!m_pCurReleasePool)
{
push();
}
CCAssert(m_pCurReleasePool, "current auto release pool should not be null");
return m_pCurReleasePool;
}