iOS 용 타워 디펜스 게임을 당분간 사용 해왔다. Cocos2d (v0.99.5 확실하지 않음)를 사용하고 있습니다. 최근 스프라이트 제거를 시작할 때 몇 가지 문제가 발생하기 시작했습니다.스프라이트 메모리 문제의 Cocos2d 제거를 디버그하는 방법
악기와 좀비를 사용하여 프로파일을 가지고 여기에 내가 무엇을 얻을 :
코드를 (및 삭제) 업데이트에있는 스프라이트를 업데이트 :
-(void) update:(ccTime)deltaTime {
if (paused)
return;
CCArray *childs = [textureAtlas children];
//Update all objects
for (GameSprite *tempChar in childs) {
if ([tempChar respondsToSelector:@selector(updateStateWithDeltaTime:andListOfGameObjects:andAtlas:)]) {
[(GameSprite*)tempChar updateStateWithDeltaTime:deltaTime andListOfGameObjects:[textureAtlas children] andAtlas:textureAtlas];
}
}
//Remove dead projectiles
for (GameSprite *tempChar in childs) {
if ([tempChar isKindOfClass:Projectile.class]) { //(**)
if (![tempChar alive]) {
[tempChar remove];
}
}
}
//Remove dead towers
for (GameSprite *tempChar in childs) {
if ([tempChar isKindOfClass:Tower.class]) {
if (![tempChar alive]) {
[tempChar remove];
}
}
}
//Remove dead creeps
for (GameSprite *tempChar in childs) {
if ([tempChar isKindOfClass:Creep.class]) {
if (![tempChar alive]) {
[tempChar remove];
}
}
}
}
제거 방법 GameSprite.m :
-(void)remove {
CCLOG(@"remove");
[self removeFromParentAndCleanup:YES];
}
첫 번째 블록은 SpriteBatchNode/textureAtlas에서 스프라이트를 업데이트합니다. 세 개의 나머지 블록은 삭제해야 할 다른 객체를 검사합니다. (그들의 alive-variable을 NO로 설정)? 세 가지 유형의 블록이있는 이유는 발사체가 (약한) 크립에 대한 참조를 가지고 있기 때문입니다. 크립이 발생하기 전에 삭제해야합니다.
내 문제는 발사체가 크립을 치고 프로 기어 (그리고 그 크립에서 발사하는 다른 모든 발사체)를 제거 할 때 무작위로 충돌한다는 것입니다. 크립 참조 수는 0으로 떨어지지 만 여전히 하위 배열에있는 것으로 보입니다. 원인 이해가 오류가 있습니다 : 나는 (**)
로 표시된 행에
*** -[NormalProjectile isKindOfClass:]: message sent to deallocated instance 0xff33e30
어느 쪽의 문제는 나를적인 Cocos2D의 removeFromParentAndCleanUP을 이해하는 것입니다 : 또는 발사체-크리프을 처리하기위한 내 "솔루션" - 관계는 기억의 관점에서 나쁘다. 이 문제를 해결하거나 디버깅하는 방법에 대한 아이디어가 있습니까?
감사합니다. 3 개의 새로운 배열을 생성하고이를 통해 열거함으로써이를 해결했습니다. 이것을 건너 뛰고 싶었지만 textureAtlas의 자식을 반복하는 것이 안전한 방법은 아닙니다. – Sunkas
더 안전한 기술을 사용하여 효과가 있음을 확인하는 것이 좋습니다. 정말 올바른 접근 방식입니다. – johnbakers