I have a problem with three clases. The the first class is called Player. This class has an NSMutableArray inside it called units. This array is made up of objects of the class Unit. This class in turn, has an NSMutableArray called bullets. It works like this:
At a certain point the class Player (it could just be the ViewController instead) adds an object to the units. Then, when an instance of Unit is initialized, as a result of the above, it creates an NSTimer that is in charge of creating bullets every second.
The thing is, is crashes somewhere in the middle of this with a SIGABRT that tells me that there was an exception because: Collection <__NSArrayM: 0xb1a2970> was mutated while being enumerated. Also, I took away the line that created bullets and it stops crashing, proving that is the problem. What does that mean!
Here is a bit of executable code that might work:
ViewController.h (instead of player)
@interface ViewController : UIViewController
{
NSMutableArray *units;
NSTimer *updateTimer;
}
-(void)Update;
ViewController.m
@implementation ViewController
//methods...
- (void)viewDidLoad
{
//more default code
//Initialized array and adds one object with the default constructor for simplicity
units = [[NSMutableArray alloc] initWithObjects:[[Unit alloc] init], nil]
}
-(void)Update
{
for(Unit *unit in units)
{
[unit Update];
if(unit.deleteFromList)
[units removeObject:unit];
}
}
//More methods
@end
Unit.h
@interface Unit : NSObject
{
NSMutableArray *bullets;
NSTimer *bulletTimer;
boolean deleteFromList;
}
@property(readonly, assign)deleteFromList;
-(void)Fire;
-(void)Update;
Unit.m
@implementation Unit
@synthesize deleteFromList;
-(id)init
{
if(self)
{
bullets = [[NSMutableArray alloc] init];
bulletTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(fire) userInfo:NULL repeats:true];
deleteFromList = false;
}
return self;
}
-(void)Fire
{
[bullets addObject:[[Bullet alloc] init]];
}
-(void)Update
{
for(Bullet *bullet in bullets)
{
[bullet Update];
if(bullet.deleteFromList)
[bullets removeObject:bullet];
}
if(certainCondition)
deleteFromList = true;
}
The bullet class will be omitted because the contents are irrelevant to what happens. Also, all the classes and constructors were shortened because the rest is useless for this example
EDIT:
Another thing I forgot to add is that the timer is created in an enumeration of the NSMutableArray units in the update method i’m about to add. I’m also adding a variable to Unit and Bullet that orders it to delete. The bullet update changes the position and also changes the deleteFromList variable
You can’t remove any item in
NSMutableArraywhile for-loop or enumerating it.Document: It is not safe to modify a mutable collection while enumerating through it. Some enumerators may currently allow enumeration of a collection that is modified, but this behavior is not guaranteed to be supported in the future.
to