Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

MythicFrost

macrumors 68040
Original poster
Mar 11, 2009
3,940
38
Australia
I'm analysing my TD game (which is made in Spritekit.) I'm focusing on my 'getTargetsForTower' method right now. The method is called in my update loop.

As you will see below 'objc_object::sideTable_retain()' and 'objc_object::sideTable_release(bool)' are consuming half of the CPU time for this method. (The statistics are after running for roughly six minutes.)

2nm8.png


I'm really not sure what they are, but I'm wondering if it is a coding mistake on my part or if this is normal?

I can post the code for the methods if wanted.

Would appreciate any info about this. I didn't have any success Googling.
 

MythicFrost

macrumors 68040
Original poster
Mar 11, 2009
3,940
38
Australia
First hit looked useful: http://stackoverflow.com/questions/19749140/optimization-what-are-sidetable-release-and-sidetable-retain.

It would definitely help to see your code, or a minimal test case which demonstrates the same behaviour.
I did also find that one, but I didn't understand all of it. Other than that, there really aren't any posts about this topic. I have ARC enabled, and all my global variables are declared with nonatomic and retain.

The method loops through the enemies on the map. Gets the tile(s) their on, loops through the towers that cover that tile (or a part of that tile) and then checks if the enemy is within the radius of the tower, and finally updates the target if it's in range. Usually an enemy is only on one tile, but as it transitions from one to another it'll be on two for a little bit.

When stress testing I might have 500 enemies and 446 towers on screen, and this method will be running as many times it can up to 60 every second. It also runs on a background thread.

Code:
- (void)getTargetsForTowers {
    NSArray *enemiesCopy = [enemiesOnMap copy];
    CCUnit *enemy;
    for (int i = 0; i < enemiesCopy.count; i++) {
        if (i < enemiesOnMap.count) {
            enemy = [enemiesOnMap objectAtIndex:i];
            [self calculateTravelDistanceForEnemy:enemy];
            
            if (enemy.actualHealth > 0) {
                NSArray *tiles = [self getTilesForEnemy:enemy];
                for (CCTileInfo *tile in tiles) {
                    CCSKTower *tower = nil;
                    for (int k = 0; k < tile.towers.count; k++) {
                        tower = [tile.towers objectAtIndex:k];
                        BOOL passes = tower.target == nil;
                        if (!passes) {
                            passes = enemy.distanceToEnd < tower.target.distanceToEnd;
                        }
                        if (passes) {
                            BOOL inRange = [self circle:tower.position withRadius:tower.attackRange collisionWithCircle:enemy.position collisionCircleRadius:1];
                            if (inRange) {
                                tower.target = enemy;
                            }
                        }
                    }
                }
            }
        }
    }
}

Thanks for your reply. I'd like to be able to get some kind of solution to this. (I can post any other methods if you'd like as well.)
 
Last edited:
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.