In this loop we have the potential to reduce the number of items in the loop while processing it. This code works fine in Obj-C, but the Swift loops don't get the message that an item has been removed and end up overflowing the array.
In Objective-C, we had:
for(int i = 4; i < staticBlocks.count; i++)
{
PlayerSprite* spr = [staticBlocks objectAtIndex:i];
[spr setPosition:CGPointMake(spr.position.x, spr.position.y-1)];
if(spr.position.y < -1000)
{
[staticBlocks removeObject:spr];
[spr removeFromParent];
}
if(spr.blockTypeIndex == Block_Type_Power_Up)
{
[spr update];
}
}
In Swift I know of these options:
//for i in 4.stride(to: staticBlocks.count, by: 1){ //crashes
//for i in 4..<staticBlocks.count{ //crashes
for var i = 4; i < staticBlocks.count; i += 1 { //works, but is deprecated
let spr = staticBlocks.objectAtIndex(i) as! PlayerSprite
spr.position = CGPointMake(spr.position.x, spr.position.y-1)
if(spr.position.y < -1000)
{
staticBlocks.removeObject(spr)
spr.removeFromParent()
//break
}
if(spr.blockTypeIndex == k.BlockType.PowerUp)
{
spr.update()
}
}
In this specific case, it really isn't a problem for me to use a break statement (which is currently commented out) to kill the loop and prevent the crash, but it doesn't seem like the proper fix. I assume there will come a time when I need to know how do do this correctly. Is there a non deprecated way to do a for loop, one which processes the count each pass?
A related, unanswered question. Is the for loop condition evalutaed each loop in swift?