Как отладить 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 для детей определенного класса. т.е. поместите все ваши снаряды в один массив во время их создания и добавления в узел пакета, после чего вы можете перебирать все снаряды, башни и т. д., просматривая эти отдельные массивы, где вы знаете, к какому классу они уже относятся. Затем удалите их из массива, а также из родительского при необходимости. Я думаю, что это немного безопаснее, чем просматривать все игровые спрайты, которые содержатся в вашем батчоде, что может включать в себя неиспользуемые спиты, а также разыгрывать их и тестировать их как разные классы.

Другие вопросы по тегам