mutating an array while enumerating

Apprentice
Posts: 15
Joined: 2009.01
Post: #1
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?
Quote this message in a reply
Member
Posts: 257
Joined: 2004.06
Post: #2
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.

The brains and fingers behind Malarkey Software (plus caretaker of the world's two brattiest felines).
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #3
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.
Quote this message in a reply
⌘-R in Chief
Posts: 1,260
Joined: 2002.05
Post: #4
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.)
Quote this message in a reply
Apprentice
Posts: 15
Joined: 2009.01
Post: #5
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.
Quote this message in a reply
⌘-R in Chief
Posts: 1,260
Joined: 2002.05
Post: #6
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.
Quote this message in a reply
Apprentice
Posts: 15
Joined: 2009.01
Post: #7
Yeah I ended up just making a nonmutable copy to loop through, works great.
Quote this message in a reply
Member
Posts: 34
Joined: 2009.01
Post: #8
Sounds like a good candidate for a mutex lock.
Quote this message in a reply
Apprentice
Posts: 15
Joined: 2009.01
Post: #9
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.
Quote this message in a reply
Member
Posts: 34
Joined: 2009.01
Post: #10
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.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  memcpy(stuct array pointer struct array point) unknown 22 11,182 Sep 29, 2005 03:16 PM
Last Post: unknown