本文適用於cocos2dxv3.17.2 - v4.0版本 (2019.5至今)
class cc_dll ref
void ref:
:retain()
void ref:
:release()
}
ref* ref:
:autorelease()
class cc_dll autoreleasepool
void autoreleasepool:
:addobject
(ref* object)
void autoreleasepool:
:clear()
// 區域性變數releasings被銷毀
}
class cc_dll poolmanager
return s_singleinstance;
}
void poolmanager:
:destroyinstance()
autoreleasepool* poolmanager:
:getcurrentpool()
const
void poolmanager:
:push
(autoreleasepool *pool)
void poolmanager:
:pop()
void director:
:mainloop()
}
根據上文我們知道,建立ref派生類例項物件的時候,建構函式會設定例項物件的引用計數為1;
而每幀渲染過後,poolmanager會執行autoreleasepool::clear() ,先將池內物件引用計數-1, 然後清空池;
假設**是這樣寫的:
auto obj= new node()
;// obj引用計數為1
while(1
)// 主迴圈
// addchild 跟蹤
void node:
:addchild
(node* child,
int localzorder,
const std:
:string &name)
void node:
:addchildhelper
(node* child,
int localzorder,
int tag,
const std:
:string &name, bool settag)
void node:
:insertchild
(node* child,
int z)
// -------------------------------------
// removechild 跟蹤
void node:
:removechild
(node* child, bool cleanup /* = true */
)void node:
:detachchild
(node *child, ssize_t childindex, bool docleanup)
void
pushback
(t object)
void
pushback
(const vector
& other)
}
~vector()
void
clear()
_data.
clear()
;}
根據上文我們知道,建立ref派生類例項物件子節點a的時候,建構函式會設定例項物件的引用計數為1;
然後父節點會使用addchild,將子節點a儲存到自身的vector屬性內,而且addchild也會呼叫ref::retain 使子節點a引用計數+1
而每幀渲染過後,poolmanager會執行autoreleasepool::clear() ,先將池內物件引用計數-1, 然後清空池;
**就變成了這樣:
auto director = director:
:getinstance()
;// 單例
auto scene = welcomescene:
:createscene()
;// createscene等同create, create呼叫了autorelease; scene引用計數為1
auto sprite = sprite:
:create
("helloworld.png");
// create 裡呼叫了autorelease; sprite引用計數為1
scene.
addchild
(sprite)
// sprite 引用計數為2
director->
runwithscene
(scene)
;// 同理通過director._scenesstack.pushback(scene); 將scene引用+1,變為2
while(1
)// director:: mainloop主迴圈
addchild 將呼叫ref::retain()
removechild 將呼叫ref::release()
obj = new node()
;// obj 引用計數為1
parent.
addchild
(obj)
// obj 引用計數+1 變為2
// a幀
// obj 被poolmanager管理
drawscene()
;poolmanager:
:getinstance()
->
getcurrentpool()
->
clear()
;// obj 引用計數-1 變為1; poolmanager 管理的當前池被清空;
// a+1幀
// obj 已經沒有被poolmanager管理
drawscene()
;poolmanager:
:getinstance()
->
getcurrentpool()
->
clear()
;// a++++++++...幀
parent.
removechild
(obj)
// obj 引用計數-1, 變為0 , 執行delete obj
cocos2dx 記憶體管理
記憶體管理中經常遇到的問題 記憶體洩露,記憶體溢位。在cocos2dx中用的是引用計數和自動釋放池的技術,由於熟悉objective c語言,所以對這兩個概念不會很陌生。一 引用計數 引用計數是自動記憶體管理的基礎 在物件裡增加乙個引用計數,當外部引用增加時,計數器加1,當外部引用消失時,計數器減1...
cocos2d x 記憶體管理
呼叫了autorelease的物件,將會在自動 池釋放的時候被釋放一次。因為這個操作發生在 mainloop drawscene 後,這時候遊戲中所有的邏輯已經執行完畢,正是釋放無效資源的最佳時機。所以乙個物件被create後,將被放進pool中,其ref 數為1,當遊戲整個邏輯跑完,如果沒有增加r...
cocos2dx 記憶體管理
我們知道,cocos2dx中使用了引用計數的方式去管理記憶體,不需要我們手動delete的去釋放記憶體。那麼cocos2dx中是怎麼實現引用計數的記憶體管理方式的呢?cocos2dx中的記憶體管理用到了兩個工具 引用計數器 ref 自動 池 autoreleasepool 引用計數器 ref ref...