0

I have a case where in my collections will be mutated while enumerating.But this is not allowed in iOS.On further investigation found that the NSFastEnumerationState is a c type struct as follows

typedef struct {
        unsigned long state;
        id *itemsPtr;
        unsigned long *mutationsPtr;
        unsigned long extra[5];
    } NSFastEnumerationState;

So state->mutationPtr denotes whether the collection was mutated or not,based on which exceptions are thrown.Can we override this to show that the collection is not mutated(even if it is mutated),So that the exceptions are not thrown.By overriding we can achieve mutation while enumeration.I don know whether this is a correct idea.Please let me know your suggestions.

Karthik207
  • 493
  • 9
  • 27
  • 2
    Why don't you copy the object you are enumerating right before enumeration? That way your copy won't change. – The dude Nov 19 '13 at 11:08
  • ^This way or access to collection from single thread, for example Main Thread. Just wrap your code where needed: `dispatch_async(dispatch_get_main_queue(), ^{ ... });` – k06a Nov 19 '13 at 11:10
  • Why not just use a normal for loop? I don't know of many containers that are mutable and don't provide another way of iteration. – Richard J. Ross III Nov 19 '13 at 11:26

1 Answers1

2

The idea is incorrect, just copy the object you are enumerating and enumerate the copy.

Edit: To address your comments, it seems that it's technically possible to achieve what you want. First thing I did is to go to the NSEnumerator documentation to check if you could basically create your own enumerator and implement a custom nextObject method to resolve the problem. This is what I found:

Note: 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.

Additionally, I checked the Enumeration: Traversing a Collection’s Elements - Using an Enumerator section and I found a very similar thing:

It is not safe to remove, replace, or add to a mutable collection’s elements while enumerating through it. If you need to modify a collection during enumeration, you can either make a copy of the collection and enumerate using the copy or collect the information you require during the enumeration and apply the changes afterwards.

So if you sum this all up, it seems to me that you have 2 options:

  1. Create your custom NSEnumerator subclass and use it to do what you need.
  2. Don't use NSFastEnumeration at all and find another way to do what you need.
lawicko
  • 7,246
  • 3
  • 37
  • 49