2

Actually I receive a somehat strange exception: I iterate a MutableDictionary and want to aset a new value in it:

    selectionIndex = [NSMutableDictionary dictionaryWithDictionary:selection];
    NSString *whatever = @"999999";
    id keys;
    NSEnumerator *keyEnum = [selectionIndex keyEnumerator];

    while (keys = [keyEnum nextObject]) 
    {
        [selectionIndex setObject:whatever forKey:keys];
    }

Btw, selection, that is passed to this method is a MutableDictionary. If I run this code, I receive the following exception:

2011-12-05 15:28:05.993 lovelini[1333:207] * Terminating app due to uncaught exception 'NSGenericException', reason: '* Collection <__NSCFDictionary: 0x6a33ed0> was mutated while being enumerated.{type = mutable dict, count = 8, entries => 0 : {contents =

Ok, I know that I can't change NSDictionary, but as far as I see it, I don't! So why do I get this exception? Is this a restriction of Fast Enumeration??? As far as I know it is not possible to add or remove entries within Fast Enumeration, but I don't add or remove anything?!

usermho
  • 207
  • 4
  • 11
  • In your code sample, you aren't actually using fast enumeration. Fast enumeration would be `for (id key in keyEnum) { ... }` – Jakob Egger Dec 05 '11 at 15:13

5 Answers5

9

You cannot make any changes to a collection while enumerating it. You could instead enumerate the keys of the dictionary instead of the dictionary itself:

for (NSString *key in selectionIndex.allKeys) {
    [selectionIndex setObject:whatever forKey:key];
}
omz
  • 53,243
  • 5
  • 129
  • 141
2

That is a bad idea to change the value while enumerating it, you can collect the elements into a new dictionary, then replace the original dictionary with the new one.

changx
  • 1,937
  • 1
  • 13
  • 10
1

Fast enumeration in only meant for viewing objects in collection. You can't modify elements.

Enumeration is “safe”—the enumerator has a mutation guard so that if you attempt to modify the collection during enumeration, an exception is raised. AppleDeveloperPortal

Ben Mosher
  • 13,251
  • 7
  • 69
  • 80
igofed
  • 1,402
  • 1
  • 9
  • 15
  • Technically, you _can_ modify elements: if you have an `NSMutableArray` of `NSMutableString`s, you could modify the strings during enumeration; what you can't do is _add_ or _remove_ them. – Ben Mosher Aug 10 '12 at 15:37
0

NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];

    NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:nil delegateQueue:nil];


    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/services/userDATE.php?user_id=%@",MAINDOMAINURL,[[NSUserDefaults standardUserDefaults] objectForKey:@"USERID"]]];



    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
                                                           cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                       timeoutInterval:60.0];


    NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if (error == nil)
        {
            NSMutableDictionary *jsonDict = [[NSMutableDictionary alloc]init];
            jsonDict=[NSJSONSerialization JSONObjectWithData:data options:0 error:nil];

            NSLog(@"DATA:%@",jsonDict);

            NSLog(@"driver tracking ::%@",[jsonDict objectForKey:@"response"]);
            if ([[jsonDict objectForKey:@"avialabity"] isEqualToString:@"yes"]) {


                    isDriverTracking=YES;
                    dispatch_async(dispatch_get_main_queue(), ^{
                        [self hideActivityIndicator];
                        [self performSegueWithIdentifier:@"FIRSTSEGUE" sender:nil];
                    });


            }else{
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self hideActivityIndicator];
                    [self performSegueWithIdentifier:@"SECONDSEGUE" sender:nil];
                });
            }
            [self hideActivityIndicator];

        }else [self customeAlertController:@"Alert !" :@"Plese check Your internet connection."];
    }];
    [postDataTask resume];

I GOT SAME ERROR was mutated while being enumerated.

datha
  • 359
  • 2
  • 14
0

Yes, you are adding something to the thing you're enumerating over:

[selectionIndex setObject:

It's not a restriction of fast enumeration, but of enumeration generally. Fast enumeration is a more convenient (and actually faster) way of doing enumeration. (See this comparison.)

Bottom line: don't fiddle with the contents of a collection while you're enumerating over it, you'll have problems.

Community
  • 1
  • 1
occulus
  • 16,959
  • 6
  • 53
  • 76