快速列举中的突变?

时间:2011-12-05 14:46:43

标签: iphone objective-c ios cocoa-touch

实际上我收到了一个奇怪的例外:我迭代一个MutableDictionary并希望在其中设置一个新值:

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

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

Btw,selection,传递给这个方法的是一个MutableDictionary。如果我运行此代码,我会收到以下异常:

  

2011-12-05 15:28:05.993 lovelini [1333:207] *由于未捕获的异常终止应用程序' NSGenericException',原因:' * 收藏< __ NSCFDictionary:0x6a33ed0>在被枚举时被突变。{type = mutable dict,count = 8,   entries =>       0:{contents =

好的,我知道我无法改变NSDictionary,但据我所知,我不知道!那么为什么我会得到这个例外呢?这是快速枚举的限制吗?据我所知,无法在快速枚举中添加或删除条目,但我没有添加或删除任何内容?!

5 个答案:

答案 0 :(得分:9)

枚举时,您无法对集合进行任何更改。您可以改为枚举字典的键而不是字典本身:

for (NSString *key in selectionIndex.allKeys) {
    [selectionIndex setObject:whatever forKey:key];
}

答案 1 :(得分:2)

在枚举时更改值是个坏主意,您可以将元素收集到新字典中,然后用新字典替换原始字典。

答案 2 :(得分:1)

快速枚举仅适用于查看集合中的对象。你无法修改元素。

枚举是“安全的” - 枚举器具有变异防护,因此如果您在枚举期间尝试修改集合,则会引发异常。 AppleDeveloperPortal

答案 3 :(得分:0)

是的,您正在为您要枚举的内容添加一些内容:

[selectionIndex setObject:

这不是快速枚举的限制,而是一般的枚举。快速枚举是一种更方便(实际上更快)的枚举方式。 (见this comparison。)

结论:当你对它进行枚举时,不要弄乱集合的内容,你会遇到问题。

答案 4 :(得分: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在被枚举时发生了变异。