Как отладить Cocos2d удаление проблемы памяти спрайтов
Уже некоторое время работаю над игрой Tower Defense для iOS. Я использую Cocos2d (v0.99.5 не уверен). Недавно начал сталкиваться с некоторыми проблемами, когда я начал удалять спрайты.
Есть профили с использованием инструментов и зомби, и вот что я получаю:
Код для обновления спрайтов (а также их удаления) находится в обновлении:
-(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. Три оставшихся блока проверяют различные объекты, если они должны быть удалены. (их живая переменная установлена в NO?). Причина, по которой у меня есть три блока разных типов, связана с тем, что снаряды имеют (слабую) ссылку на ползучесть, по которой они стреляют, и должны быть удалены перед ползучестью.
Так что моя проблема в том, что он случайно падает, когда снаряд попадает в крипа, и снаряд (и все другие снаряды, стреляющие в этого крипа) должны быть удалены). Счетчик ссылок Creeps уменьшается до 0, но, похоже, все еще находится в массиве childs. Причина ошибки, которую я получаю:
*** -[NormalProjectile isKindOfClass:]: message sent to deallocated instance 0xff33e30
в ряду я отметил (**)
Либо проблема заключается в том, что я понимаю, что у Cocos2d есть команда removeFromParentAndCleanUP, либо в том, что мое "решение" для обработки отношения projectile-creep-отношениях плохо с точки зрения памяти. Любые идеи о том, как решить эту проблему или отладить ее дальше?
1 ответ
Ваши быстрые методы перечисления для прохождения массива приводят все ваши спрайты в этом массиве в качестве собственного подкласса CCSprite, а затем проверяют, не являются ли они другим пользовательским подклассом, таким как Tower, и т. Д. Я не считаю это полезным практика программирования, поскольку методы в одном классе не могут быть в другом, но, тем не менее, вы применяете их.
Это может или не может способствовать вашей проблеме, но разумный подход заключается в том, чтобы сохранить assign
iVar CCArray для детей определенного класса. т.е. поместите все ваши снаряды в один массив во время их создания и добавления в узел пакета, после чего вы можете перебирать все снаряды, башни и т. д., просматривая эти отдельные массивы, где вы знаете, к какому классу они уже относятся. Затем удалите их из массива, а также из родительского при необходимости. Я думаю, что это немного безопаснее, чем просматривать все игровые спрайты, которые содержатся в вашем батчоде, что может включать в себя неиспользуемые спиты, а также разыгрывать их и тестировать их как разные классы.