-----------------華麗麗的分割線------------------------
[cocos2dx]--我創建了一個Sprite的物件aSprite(Sprite創建的是一個autoRelease物件).并把它作為實參傳遞到一個函式.在這個函式里面我把aSprite先retain后再賦給類成員變數bSprite,之后把bSprite再addChild到一個面板里面.現在我要怎么做bSprite的釋放呢?
1.autoRelease物件的不同之處在哪里?它是在什么時候和怎么釋放的(手動呼叫release會影響到它嗎?)
2.這個函式運行結束后,aSprite指向的記憶體計數是多少?它是什么時候被釋放回收呢?
3.bSprite被賦值aSprite再addChild后,計數應該是3,函式結束后應該變為2,那這個類析構的時候我需要再把bSprite去release兩次才可以把bSprite真正釋放?可它不是autoRelease嗎?...........................暈了
uj5u.com熱心網友回復:
1,重寫dealloc函式 ,物件釋放時會自動呼叫這個函式,里面列印個log看看2,int i=[bSprite retainCount]; i=0的時候說明已經釋放
uj5u.com熱心網友回復:
還有一個,如果我retain一次一個autoRelease物件,我卻release了2次這個物件,那會發生什么?uj5u.com熱心網友回復:
已經釋放了,物件就是nil了 再Release什么也不會發生了
uj5u.com熱心網友回復:
可是它不為0..uj5u.com熱心網友回復:
是不是autoRelease物件除了手動retain或release,其它的比如創建,添加到其它父面板的記憶體計數都是自動加減的?uj5u.com熱心網友回復:
可是它不為0..
1,重寫dealloc函式 ,物件釋放時會自動呼叫這個函式,里面列印個log看看
2,int i=[bSprite retainCount]; i=0的時候說明已經釋放
不為0就是你沒釋放,要么是類成員變數不用bSprite的時候沒釋放,要么是類成員變數死的時候沒釋放
uj5u.com熱心網友回復:
可是它不為0..
1,重寫dealloc函式 ,物件釋放時會自動呼叫這個函式,里面列印個log看看
2,int i=[bSprite retainCount]; i=0的時候說明已經釋放
不為0就是你沒釋放,要么是類成員變數不用bSprite的時候沒釋放,要么是類成員變數死的時候沒釋放
void TestAutoReleaseClass::setBSprite(Sprite *aSprite)
{
aSprite->retain();
m_bSprite= aSprite;
if(aSprite){
this->addChild(m_bSprite, 0);
this->setContentSize(m_bSprite->getContentSize());
}
}
當我這個類析構的時候我release一次m_bSprite,但是release之后它的計數是1.我還需要再release一次,還是說自動記憶體池會幫我清空,如果是,那記憶體池又是什么時候執行清空的?
uj5u.com熱心網友回復:
void TestAutoReleaseClass::setBSprite(Sprite *aSprite)
{
if(m_bSprite!= aSprite){//這樣寫比較嚴謹
m_bSprite=[aSprite retain];
}
if(aSprite){
this->addChild(m_bSprite, 0);
this->setContentSize(m_bSprite->getContentSize());
}
}
uj5u.com熱心網友回復:
void TestAutoReleaseClass::setBSprite(Sprite *aSprite)
{
if(m_bSprite!= aSprite){//這樣寫比較嚴謹
[m_bSprite release];
m_bSprite=[aSprite retain];
}
if(aSprite){
this->addChild(m_bSprite, 0);
this->setContentSize(m_bSprite->getContentSize());
}
}
uj5u.com熱心網友回復:
//參考計數
//retain(); //+1
//release(); //-1
//autorelease(); //+1,并且將物件添加到參考計數池(AutoreleasePool)里面,這個池在當前訊息回圈結束后,會將它里面的所有物件呼叫一次release();
//假設某個按鈕點擊函式
CXXX::onBtn(Ref* sender) {
Sprite* s = Sprite::create("a.jpg"); //Node及其子類的create函式一般都會呼叫autorelease(); //此時_referenceCount = 1;
//此時如果啥都不干時,退出當前訊息回圈,池會呼叫release(); //此時_referenceCount = 0并釋放物件....
}
//假設另外一個按鈕點擊函式
CXXX::onBtn2(Ref* sender) {
Sprite* s = Sprite::create("a.jpg"); //Node及其子類的create函式一般都會呼叫autorelease(); //此時_referenceCount = 1;
parent->addChild(s); //Node及其子類的addChild()函式鏃會呼叫retain(); //此時_referenceCount = 2;
//退出當前訊息回圈,池會呼叫release(); //此時_referenceCount = 1并釋放物件....
//此時木有釋放物件.除非你呼叫
//parent->removeChild(s); //Node及其子類的removeChild()函式鏃會呼叫release(); //此時_referenceCount = 0并釋放物件....
}
uj5u.com熱心網友回復:
誰retain()了,就由誰release();autorelease()由AutoreleasePool來release();
uj5u.com熱心網友回復:
//退出當前訊息回圈,池會呼叫release(); //此時_referenceCount = 1并釋放物件....這一句應該是
//退出當前訊息回圈,池會呼叫release(); //此時_referenceCount = 1不釋放
uj5u.com熱心網友回復:
你這個程序中,由于參考計數的機制 create的時候,參考計數為1,然后 autorelease ,在mainloop執行完成后進行(也就是一幀執行完) 自動釋放池的push操作,但是由于 sprite 加入了scen中,參考計數又加1 所以 他可以一直在螢屏上面顯示,當呼叫removefromParent函式的時候才會被銷毀
你的問題是 將asprite作為實參傳遞,這個時候是沒有引起參考計數的改變的 ,唯一引起改變的就是你自己的retain 和 addchild 這兩個方法導致你的參考計數為3 ,所以 在使用的時候,retain 一次就要release一次,而系統的 addchild 引發的參考計數問題你是不用管的,
口訣 : 誰創建誰釋放,誰保留誰釋放,autorelease延遲釋放,池中的所有物件參考計數減一
uj5u.com熱心網友回復:
1.cocos 的 autorelease 是個很奇怪的東西,任何 object 物件 如果呼叫了 autorelease 方法后,它的 auto計數都會 +1,過了本幀以后, autorelese池會釋放其一次,且auto計數歸 02.任何 node append 到父 node 之后都會自動 retain, 從父 node 移除時都會自動release一次
3.手動 retain 的,使用完了 請手動 release, 否則記憶體泄漏
uj5u.com熱心網友回復:
這個東西是從 智能指標那塊搞過來的 每次retain會增加參考計數當參考計數為0 的時候 說明此資源無人使用 系統自動回收
問題是這垃圾回收觸發是在你最后一次呼叫Release的時候立即執行
其造成的后果就是 當資源參考值很少的時候 很容易觸發大量的 new 和 delete 造成記憶體碎片不說,會使得游戲卡頓
uj5u.com熱心網友回復:
autorelease 其實類似于一個開關,通過物件的參考計數來確定這個物件是否需要被釋放。
而影響參考計數的方法是retain(+1),和release(-1),當參考計數為0的時候,證明這個物件已經沒有任何用處了,執行delete釋放記憶體。
如果你使用了autorelease,請不要自作聰明的去手動release。release應該是和retain成對出現在你的代碼中的。而且,如果你再析構里再release,我認為應該會出現一個死回圈。
uj5u.com熱心網友回復:
1.autoRelease物件的不同之處在哪里?它是在什么時候和怎么釋放的(手動呼叫release會影響到它嗎?)autoRelease的物件是引擎自動處理的,當其被add到父節點下的時候會自動retain,父節點移除的時候,會release子節點。手動呼叫release會提前將其參考計數變為0,會被清除,如果,這個時候父節點還有其參考,程式應該會崩潰。
2.這個函式運行結束后,aSprite指向的記憶體計數是多少?它是什么時候被釋放回收呢?
參考計數應該是2,因為retain和addChild都會增加他的參考計數,想要釋放他要進行一次release和removeFromParent
3.bSprite被賦值aSprite再addChild后,計數應該是3,函式結束后應該變為2,那這個類析構的時候我需要再把bSprite去release兩次才可以把bSprite真正釋放?可它不是autoRelease嗎?
你這個理解是錯誤的,參考計數針對的是記憶體,而不是指標,賦值操作不會增加參考計數,所以,參考計數應該是2,而不是3.至于為什么要release兩次,是因為你手動retain了一次,并且,你release兩次這種操作也欠妥,因為,這個精靈是有父節點的,父節點呼叫到他的時候可能是物件已經被清除,所以,在這里正確的處理方式應該是先removeFromParent,在release這樣,將子節點和父節點之間的關系斷開。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/67522.html
標籤:Cocos2d-x
