cocos2dx3.2 场景切换 真机卡死

时间:2023-02-07 23:38:10
例如:scene1    scene2    scene3

scene1 ;

replacescene(scene2);

scenen2;

replacescene(scene3);

scene3;

replacescene(scene1);

如此循环 第一次没问题,    当第二轮scene1--->scene2 时会卡死;
scene2中的对象都已释放 


且只在真机上卡死  电脑上没问题 

21 个解决方案

#1


这样不好判断,你试试用调试模式在电脑上运行,看看有没有报错?
有些错误要调试模式下才会发生

#2


现在又出现了新问题。
init(){
Armature * player;//创建并初始化
ccsprite * sprite = (CCSprite*)player;
this->addchile(sprite);

}
就是在前面加载了一个cocos动画
当replaceScene()后 会发生访问冲突
在这里
 /** Returns the Command type */
    inline Type getType() const { return _type; }

但是注销掉/*this->addchile(sprite);*/
就不会了

#3


引用 2 楼 E_ver_Fe 的回复:
现在又出现了新问题。
init(){
Armature * player;//创建并初始化
ccsprite * sprite = (CCSprite*)player;
this->addchile(sprite);

}
就是在前面加载了一个cocos动画
当replaceScene()后 会发生访问冲突
在这里
 /** Returns the Command type */
    inline Type getType() const { return _type; }

但是注销掉/*this->addchile(sprite);*/
就不会了

Armature 不能转成CCSprite吧?

#4


可以的。。。

#5


引用 4 楼 E_ver_Fe 的回复:
可以的。。。


class  Armature : public cocos2d::Node, public cocos2d::BlendProtocol

明显没有继承关系吖,真的可以转么?我没试过...

我看的是3.0的版本,不知道是不是2.x版本有继承关系

#6


木头GG  replaceScene到下一场景后    会释放自动原场景的所有缓存吗(动画   UI   图片  等等 )包括头文件中定义的成员

#7


木头GG  replaceScene到下一场景后    会释放自动原场景的所有缓存吗(动画   UI   图片  等等 )包括头文件中定义的成员

#8


木头GG  replaceScene到下一场景后    会释放自动原场景的所有缓存吗(动画   UI   图片  等等 )包括头文件中定义的成员

#9


引用 8 楼 E_ver_Fe 的回复:
木头GG  replaceScene到下一场景后    会释放自动原场景的所有缓存吗(动画   UI   图片  等等 )包括头文件中定义的成员

正常情况下会,
但也要看你用了什么对象,比如Cocostudio的某些对象要自己调用释放(不知道现在优化了没)

自己retain了没有release也会造成内存泄漏,诸如此类

#10


create 的局部对象变量要手动释放吗,主要是ccsprite   和  ccarry

#11


CCSpriteFrameCache::sharedSpriteFrameCache()->removeUnusedSpriteFrames();
CCTextureCache::sharedTextureCache()->removeAllTextures();
CCArmatureDataManager::purge();
CCAnimationCache::purgeSharedAnimationCache(); 
GUIReader::shareReader()->purgeGUIReader();
CCDirector::sharedDirector()->purgeCachedData();
每次切换场景都会执行一次的但是看输出貌似只有第一句执行有效果  其他的没效果

#12


create的要看你有没有retain(包括主动的或者被动的,被动的一般不需要去管),你可以看看内存管理的文章,蛮多的,看几篇大概就知道了~

#13


cocosstudio   资源用什么去手动释放好了
CCTextureCache::sharedTextureCache()->removeAllTextures();
CCArmatureDataManager::purge();
CCAnimationCache::purgeSharedAnimationCache(); 
GUIReader::shareReader()->purgeGUIReader();
CCDirector::sharedDirector()->purgeCachedData();
这些貌似都没效果

#14



ccarray * arr =  ccarry::create();arr->retain();
for(intt i = 0;i<10;i++)
{
    ccsprite * spr = ccsprite::create("");
    arr->addobject(spr);
}
arr->release();
这样所有的sprite都会释放吗?还是要重新遍历一次逐个释放?

#15


引用 14 楼 E_ver_Fe 的回复:
ccarray * arr =  ccarry::create();arr->retain();
for(intt i = 0;i<10;i++)
{
    ccsprite * spr = ccsprite::create("");
    arr->addobject(spr);
}
arr->release();
这样所有的sprite都会释放吗?还是要重新遍历一次逐个释放?

会释放的...
如果你还有疑惑,请看看内存管理的文章,不然内存泄露的概率是大大的~
浅层次的内存应用,可以看看我这篇:http://www.benmutou.com/archives/61
更深层次的可以到中文官网搜索一下,或者看红孩儿那篇,比较经典

#16


Struct  myst{
   CCArray * arr1;
    CCArray * arr2;
    CCArray * arr3;
} st;
myst releaseArray(myst   s){
  s.arr1->release();
  s.arr2->release();
  s.arr3->release();
  return s;
}

CCSprite * spr1 = CCSprite::create();
CCSprite * spr2 = CCSprite::create();
CCSprite * spr3 = CCSprite::create();

st.arr1->addobject(spr1);   st.arr1->addobject(spr2);    st.arr1->addobject(spr3);
st.arr2->addobject(spr1);
st.arr3->addobject(spr3);

/////////////////////////////////////////退出时
cclog("%d",st.arr1.getreferencecount());
cclog("%d",st.arr2.getreferencecount());
cclog("%d",st.arr3.getreferencecount());
st = releaseArray(st);

如上所示:就是那么一个自定义的释放程序
如果单独新建一个工程去运行的话没问题,但是放在游戏中执行releaseArray就会报Expression: !_running异常;
而且只有arr1->release()报错.

而且游戏中执行releaseArray前的打印结果是:
1
1
1
执行前打印spr1/spr2/spr3的引用计数分别是
2
1
2
求大神帮忙想想可能是哪里出错了。。。
木头GG   
waiting  for you   !!!!!!!!!!!!!! cocos2dx3.2 场景切换 真机卡死


#17


引用 16 楼 E_ver_Fe 的回复:
Struct  myst{
   CCArray * arr1;
    CCArray * arr2;
    CCArray * arr3;
} st;
myst releaseArray(myst   s){
  s.arr1->release();
  s.arr2->release();
  s.arr3->release();
  return s;
}

CCSprite * spr1 = CCSprite::create();
CCSprite * spr2 = CCSprite::create();
CCSprite * spr3 = CCSprite::create();

st.arr1->addobject(spr1);   st.arr1->addobject(spr2);    st.arr1->addobject(spr3);
st.arr2->addobject(spr1);
st.arr3->addobject(spr3);

/////////////////////////////////////////退出时
cclog("%d",st.arr1.getreferencecount());
cclog("%d",st.arr2.getreferencecount());
cclog("%d",st.arr3.getreferencecount());
st = releaseArray(st);

如上所示:就是那么一个自定义的释放程序
如果单独新建一个工程去运行的话没问题,但是放在游戏中执行releaseArray就会报Expression: !_running异常;
而且只有arr1->release()报错.

而且游戏中执行releaseArray前的打印结果是:
1
1
1
执行前打印spr1/spr2/spr3的引用计数分别是
2
1
2
求大神帮忙想想可能是哪里出错了。。。
木头GG   
waiting  for you   !!!!!!!!!!!!!! cocos2dx3.2 场景切换 真机卡死

cocos2dx3.2 场景切换 真机卡死
在你把Cocos2d-x基础看完之前,我拒绝继续回答~!

这是最后一次回答....结构体里的那些CCArray * arr1对象,你得先赋值了,才能使用,如:st.arr1 = CCArray::create();

cocos2dx3.2 场景切换 真机卡死再问我这种问题,我就..我就引咎辞职~!

#18


引用
结构体里的那些CCArray * arr1对象,你得先赋值了,才能使用,如:st.arr1 = CCArray::create();

我想说   程序中的代码是能执行通过的 而且运行结果没问题    所以。。所以那个CCArray::create()都加了的。。。
上面那个只是概述一下程序的代码流程和出现的问题。。。
只是在那三个重叠的CCArray中最大的那一个  release()没效果   或者执行异常啊。。。不是语法错误。。
我还是自己想办法去了。。

#19


再说明白点就是创建一个场景,  场景内有多种元素,把各种元素分别保存在不同的CCArray的同时
再定义一个CCArray * allarray  把所有的元素也都保存起来,然后遍历allarray 把所有的元素都添加到场景中
所以在程序中一共add了3次  分别是分类CCArray  、allarray、场景;
场景addchild()同时release()一次    最后游戏结束时   对所有的CCarray   release()。。。。。

#20


CCSprite *spr_1 = CCSprite::create("HelloWorld.png");	
arr = CCArray::create();arr->retain();
arr1 = CCArray::create();arr1->retain();
arr2 = CCArray::create();arr2->retain();
arr->addObject(spr_1);
arr1->addObject(spr_1);
arr2->addObject(spr_1);
CCLog("arr=%d",arr->getReferenceCount());
CCLog("arr1=%d",arr1->getReferenceCount());
CCLog("arr2=%d",arr2->getReferenceCount());
CCLog("spr=%d",spr_1->getReferenceCount());
CCLog("``````````````````");
arr->release();arr1->release();arr2->release();
CCLog("arr=%d",arr->getReferenceCount());
CCLog("arr1=%d",arr1->getReferenceCount());
CCLog("arr2=%d",arr2->getReferenceCount());
CCLog("spr=%d",spr_1->getReferenceCount());


打印结果:
arr=2
arr1=2
arr2=2
spr=4
``````````````````
arr=1
arr1=1
arr2=1
spr=4


真心无力了。。。。

#21


引用 20 楼 E_ver_Fe 的回复:
CCSprite *spr_1 = CCSprite::create("HelloWorld.png");	
arr = CCArray::create();arr->retain();
arr1 = CCArray::create();arr1->retain();
arr2 = CCArray::create();arr2->retain();
arr->addObject(spr_1);
arr1->addObject(spr_1);
arr2->addObject(spr_1);
CCLog("arr=%d",arr->getReferenceCount());
CCLog("arr1=%d",arr1->getReferenceCount());
CCLog("arr2=%d",arr2->getReferenceCount());
CCLog("spr=%d",spr_1->getReferenceCount());
CCLog("``````````````````");
arr->release();arr1->release();arr2->release();
CCLog("arr=%d",arr->getReferenceCount());
CCLog("arr1=%d",arr1->getReferenceCount());
CCLog("arr2=%d",arr2->getReferenceCount());
CCLog("spr=%d",spr_1->getReferenceCount());


打印结果:
arr=2
arr1=2
arr2=2
spr=4
``````````````````
arr=1
arr1=1
arr2=1
spr=4


真心无力了。。。。

这种建议你再看一遍红孩儿那篇(或者到泰然网找一篇),你会找到答案的...

如果你已经看过的话...
这里的答案是 “在游戏的下一帧才会释放这些对象,所以你在当前帧打印是看不出来的,它们都还没有被释放,所以精灵也不会被释放”
原因在那些文章里可以找到,我就不长篇大论了~

#1


这样不好判断,你试试用调试模式在电脑上运行,看看有没有报错?
有些错误要调试模式下才会发生

#2


现在又出现了新问题。
init(){
Armature * player;//创建并初始化
ccsprite * sprite = (CCSprite*)player;
this->addchile(sprite);

}
就是在前面加载了一个cocos动画
当replaceScene()后 会发生访问冲突
在这里
 /** Returns the Command type */
    inline Type getType() const { return _type; }

但是注销掉/*this->addchile(sprite);*/
就不会了

#3


引用 2 楼 E_ver_Fe 的回复:
现在又出现了新问题。
init(){
Armature * player;//创建并初始化
ccsprite * sprite = (CCSprite*)player;
this->addchile(sprite);

}
就是在前面加载了一个cocos动画
当replaceScene()后 会发生访问冲突
在这里
 /** Returns the Command type */
    inline Type getType() const { return _type; }

但是注销掉/*this->addchile(sprite);*/
就不会了

Armature 不能转成CCSprite吧?

#4


可以的。。。

#5


引用 4 楼 E_ver_Fe 的回复:
可以的。。。


class  Armature : public cocos2d::Node, public cocos2d::BlendProtocol

明显没有继承关系吖,真的可以转么?我没试过...

我看的是3.0的版本,不知道是不是2.x版本有继承关系

#6


木头GG  replaceScene到下一场景后    会释放自动原场景的所有缓存吗(动画   UI   图片  等等 )包括头文件中定义的成员

#7


木头GG  replaceScene到下一场景后    会释放自动原场景的所有缓存吗(动画   UI   图片  等等 )包括头文件中定义的成员

#8


木头GG  replaceScene到下一场景后    会释放自动原场景的所有缓存吗(动画   UI   图片  等等 )包括头文件中定义的成员

#9


引用 8 楼 E_ver_Fe 的回复:
木头GG  replaceScene到下一场景后    会释放自动原场景的所有缓存吗(动画   UI   图片  等等 )包括头文件中定义的成员

正常情况下会,
但也要看你用了什么对象,比如Cocostudio的某些对象要自己调用释放(不知道现在优化了没)

自己retain了没有release也会造成内存泄漏,诸如此类

#10


create 的局部对象变量要手动释放吗,主要是ccsprite   和  ccarry

#11


CCSpriteFrameCache::sharedSpriteFrameCache()->removeUnusedSpriteFrames();
CCTextureCache::sharedTextureCache()->removeAllTextures();
CCArmatureDataManager::purge();
CCAnimationCache::purgeSharedAnimationCache(); 
GUIReader::shareReader()->purgeGUIReader();
CCDirector::sharedDirector()->purgeCachedData();
每次切换场景都会执行一次的但是看输出貌似只有第一句执行有效果  其他的没效果

#12


create的要看你有没有retain(包括主动的或者被动的,被动的一般不需要去管),你可以看看内存管理的文章,蛮多的,看几篇大概就知道了~

#13


cocosstudio   资源用什么去手动释放好了
CCTextureCache::sharedTextureCache()->removeAllTextures();
CCArmatureDataManager::purge();
CCAnimationCache::purgeSharedAnimationCache(); 
GUIReader::shareReader()->purgeGUIReader();
CCDirector::sharedDirector()->purgeCachedData();
这些貌似都没效果

#14



ccarray * arr =  ccarry::create();arr->retain();
for(intt i = 0;i<10;i++)
{
    ccsprite * spr = ccsprite::create("");
    arr->addobject(spr);
}
arr->release();
这样所有的sprite都会释放吗?还是要重新遍历一次逐个释放?

#15


引用 14 楼 E_ver_Fe 的回复:
ccarray * arr =  ccarry::create();arr->retain();
for(intt i = 0;i<10;i++)
{
    ccsprite * spr = ccsprite::create("");
    arr->addobject(spr);
}
arr->release();
这样所有的sprite都会释放吗?还是要重新遍历一次逐个释放?

会释放的...
如果你还有疑惑,请看看内存管理的文章,不然内存泄露的概率是大大的~
浅层次的内存应用,可以看看我这篇:http://www.benmutou.com/archives/61
更深层次的可以到中文官网搜索一下,或者看红孩儿那篇,比较经典

#16


Struct  myst{
   CCArray * arr1;
    CCArray * arr2;
    CCArray * arr3;
} st;
myst releaseArray(myst   s){
  s.arr1->release();
  s.arr2->release();
  s.arr3->release();
  return s;
}

CCSprite * spr1 = CCSprite::create();
CCSprite * spr2 = CCSprite::create();
CCSprite * spr3 = CCSprite::create();

st.arr1->addobject(spr1);   st.arr1->addobject(spr2);    st.arr1->addobject(spr3);
st.arr2->addobject(spr1);
st.arr3->addobject(spr3);

/////////////////////////////////////////退出时
cclog("%d",st.arr1.getreferencecount());
cclog("%d",st.arr2.getreferencecount());
cclog("%d",st.arr3.getreferencecount());
st = releaseArray(st);

如上所示:就是那么一个自定义的释放程序
如果单独新建一个工程去运行的话没问题,但是放在游戏中执行releaseArray就会报Expression: !_running异常;
而且只有arr1->release()报错.

而且游戏中执行releaseArray前的打印结果是:
1
1
1
执行前打印spr1/spr2/spr3的引用计数分别是
2
1
2
求大神帮忙想想可能是哪里出错了。。。
木头GG   
waiting  for you   !!!!!!!!!!!!!! cocos2dx3.2 场景切换 真机卡死


#17


引用 16 楼 E_ver_Fe 的回复:
Struct  myst{
   CCArray * arr1;
    CCArray * arr2;
    CCArray * arr3;
} st;
myst releaseArray(myst   s){
  s.arr1->release();
  s.arr2->release();
  s.arr3->release();
  return s;
}

CCSprite * spr1 = CCSprite::create();
CCSprite * spr2 = CCSprite::create();
CCSprite * spr3 = CCSprite::create();

st.arr1->addobject(spr1);   st.arr1->addobject(spr2);    st.arr1->addobject(spr3);
st.arr2->addobject(spr1);
st.arr3->addobject(spr3);

/////////////////////////////////////////退出时
cclog("%d",st.arr1.getreferencecount());
cclog("%d",st.arr2.getreferencecount());
cclog("%d",st.arr3.getreferencecount());
st = releaseArray(st);

如上所示:就是那么一个自定义的释放程序
如果单独新建一个工程去运行的话没问题,但是放在游戏中执行releaseArray就会报Expression: !_running异常;
而且只有arr1->release()报错.

而且游戏中执行releaseArray前的打印结果是:
1
1
1
执行前打印spr1/spr2/spr3的引用计数分别是
2
1
2
求大神帮忙想想可能是哪里出错了。。。
木头GG   
waiting  for you   !!!!!!!!!!!!!! cocos2dx3.2 场景切换 真机卡死

cocos2dx3.2 场景切换 真机卡死
在你把Cocos2d-x基础看完之前,我拒绝继续回答~!

这是最后一次回答....结构体里的那些CCArray * arr1对象,你得先赋值了,才能使用,如:st.arr1 = CCArray::create();

cocos2dx3.2 场景切换 真机卡死再问我这种问题,我就..我就引咎辞职~!

#18


引用
结构体里的那些CCArray * arr1对象,你得先赋值了,才能使用,如:st.arr1 = CCArray::create();

我想说   程序中的代码是能执行通过的 而且运行结果没问题    所以。。所以那个CCArray::create()都加了的。。。
上面那个只是概述一下程序的代码流程和出现的问题。。。
只是在那三个重叠的CCArray中最大的那一个  release()没效果   或者执行异常啊。。。不是语法错误。。
我还是自己想办法去了。。

#19


再说明白点就是创建一个场景,  场景内有多种元素,把各种元素分别保存在不同的CCArray的同时
再定义一个CCArray * allarray  把所有的元素也都保存起来,然后遍历allarray 把所有的元素都添加到场景中
所以在程序中一共add了3次  分别是分类CCArray  、allarray、场景;
场景addchild()同时release()一次    最后游戏结束时   对所有的CCarray   release()。。。。。

#20


CCSprite *spr_1 = CCSprite::create("HelloWorld.png");	
arr = CCArray::create();arr->retain();
arr1 = CCArray::create();arr1->retain();
arr2 = CCArray::create();arr2->retain();
arr->addObject(spr_1);
arr1->addObject(spr_1);
arr2->addObject(spr_1);
CCLog("arr=%d",arr->getReferenceCount());
CCLog("arr1=%d",arr1->getReferenceCount());
CCLog("arr2=%d",arr2->getReferenceCount());
CCLog("spr=%d",spr_1->getReferenceCount());
CCLog("``````````````````");
arr->release();arr1->release();arr2->release();
CCLog("arr=%d",arr->getReferenceCount());
CCLog("arr1=%d",arr1->getReferenceCount());
CCLog("arr2=%d",arr2->getReferenceCount());
CCLog("spr=%d",spr_1->getReferenceCount());


打印结果:
arr=2
arr1=2
arr2=2
spr=4
``````````````````
arr=1
arr1=1
arr2=1
spr=4


真心无力了。。。。

#21


引用 20 楼 E_ver_Fe 的回复:
CCSprite *spr_1 = CCSprite::create("HelloWorld.png");	
arr = CCArray::create();arr->retain();
arr1 = CCArray::create();arr1->retain();
arr2 = CCArray::create();arr2->retain();
arr->addObject(spr_1);
arr1->addObject(spr_1);
arr2->addObject(spr_1);
CCLog("arr=%d",arr->getReferenceCount());
CCLog("arr1=%d",arr1->getReferenceCount());
CCLog("arr2=%d",arr2->getReferenceCount());
CCLog("spr=%d",spr_1->getReferenceCount());
CCLog("``````````````````");
arr->release();arr1->release();arr2->release();
CCLog("arr=%d",arr->getReferenceCount());
CCLog("arr1=%d",arr1->getReferenceCount());
CCLog("arr2=%d",arr2->getReferenceCount());
CCLog("spr=%d",spr_1->getReferenceCount());


打印结果:
arr=2
arr1=2
arr2=2
spr=4
``````````````````
arr=1
arr1=1
arr2=1
spr=4


真心无力了。。。。

这种建议你再看一遍红孩儿那篇(或者到泰然网找一篇),你会找到答案的...

如果你已经看过的话...
这里的答案是 “在游戏的下一帧才会释放这些对象,所以你在当前帧打印是看不出来的,它们都还没有被释放,所以精灵也不会被释放”
原因在那些文章里可以找到,我就不长篇大论了~