iDevGames Forums
mutating an array while enumerating - Printable Version

+- iDevGames Forums (http://www.idevgames.com/forums)
+-- Forum: Development Zone (/forum-3.html)
+--- Forum: Game Programming Fundamentals (/forum-7.html)
+--- Thread: mutating an array while enumerating (/thread-1796.html)



mutating an array while enumerating - alloca - Feb 5, 2009 02:37 PM

Okay so here's how my code works: the view handles user input and when the user clicks to create a 'job' I add it into the job queue, which is just an mutable array, my game world then enumerates through the array and acts on those jobs. The problem is: occasionally when someone is adding jobs it adds them into the array while the game is enumerating through the array, which raises an exception, is there a different way I should be handling the user input or should I just handle the exception?


mutating an array while enumerating - Malarkey - Feb 5, 2009 03:02 PM

Keep another array of jobs that are added while you're enumerating over your job queue. Once done enumerating, add all the jobs from the other array.


mutating an array while enumerating - TomorrowPlusX - Feb 5, 2009 04:13 PM

I don't know about NSSet or NSDictionary, but their counterparts in C++ ( std::set and std::map ) can be mutated while being enumerated over.

But what Malarkey said is what I do when mutating std::vector or NSArray while it's being enumerated.


mutating an array while enumerating - SethWillits - Feb 5, 2009 05:41 PM

Do not enumerate over the mutable array. Make an immutable copy and enumerate over that. Any other code mutating the mutable array is fine.

Another way to do it is to not even have a mutable array. Assuming your array is small (anything under hundreds of thousands of objects Rasp), making a new array is cheap. It's very common to use an immutable array and simply replace it. (This also makes "mutating" the array [by simply replacing it] KVC/KVO friendly.)


mutating an array while enumerating - alloca - Feb 5, 2009 09:14 PM

Malarkey Wrote:Keep another array of jobs that are added while you're enumerating over your job queue. Once done enumerating, add all the jobs from the other array.

I thought about doing this but for some reason I thought I would have to enumerate over the array to add it in, of course this isn't necessarily the case so I will probably just do this.

Thanks for all the infos.


mutating an array while enumerating - SethWillits - Feb 6, 2009 01:58 PM

The only issue is that you have to know that no other place in the program is enumerating over the array even when you're merging the arrays. It's a little unsafe as a general rule. If you can guarantee it (locks or there's only ever one place enumerating), fine, but otherwise avoid the enumerating on the mutable array as I explained.


mutating an array while enumerating - alloca - Feb 6, 2009 03:20 PM

Yeah I ended up just making a nonmutable copy to loop through, works great.


mutating an array while enumerating - kalimba - Feb 6, 2009 06:54 PM

Sounds like a good candidate for a mutex lock.


mutating an array while enumerating - alloca - Feb 6, 2009 10:44 PM

It is my understanding that a lock won't work, because the array is accessed in different parts of the code, at any rate I tried locking around the enumeration and it didn't work, I also tried locking around the part where a job is added to the array and that didn't work either.


mutating an array while enumerating - kalimba - Feb 7, 2009 12:04 AM

alloca Wrote:It is my understanding that a lock won't work, because the array is accessed in different parts of the code, at any rate I tried locking around the enumeration and it didn't work, I also tried locking around the part where a job is added to the array and that didn't work either.

That's the point of the lock -- to handle the case where the array is (asynchronously) accessed in different parts of code. In order for it to work correctly, you need to lock not only the code that is adding to the array, but the code that is enumerating/modifying the array also.

Considering you found an alternative solution, this point is moot.