收集在枚举时发生变异,UITableView [英] Collection was mutated while being enumerated, UITableView

查看:160
本文介绍了收集在枚举时发生变异,UITableView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个过滤器按钮,在弹出窗口中显示UITableView。我有我的类别和全部按钮,表示没有像iTunes中那样存在过滤器。



我的applicationDelegate类中有一个NSMutableDisctionary,用于设置复选标记。应用程序启动时,仅选择全部,取消选择其他所有内容。我想要的是当选择不是All的行时,该行被选中,All被取消选择。类似地,当选择All时,带有复选标记的所有行都不再具有复选标记,并且仅选中All并带有复选标记(例如应用程序启动时)。在我的UITableView didSelectRowForIndexPath:中,我这样做了:

  MyAppAppDelegate * dmgr =(MyAppAppDelegate *)[UIApplication sharedApplication] .delegate; 
NSUInteger row = [indexPath row];
UITableViewCell * cell = [tableView cellForRowAtIndexPath:indexPath];

//所有选中的
if(row == 0){
for(NSString * key in dmgr.CategoryDictionary){
[dmgr.CategoryDictionary setObject:[ NSNumber numberWithBool:NO] forKey:key];
}
[dmgr.CategoryDictionary setObject:[NSNumber numberWithBool:YES] forKey:@All];
}

else {

cell.accessoryType = UITableViewCellAccessoryCheckmark;
NSString * key = [_categoriesArray objectAtIndex:row];
BOOL valueAtKey = [[dmgr.CategoryDictionary valueForKey:key] boolValue];
valueAtKey =!valueAtKey;
[dmgr.CategoryDictionary setObject:[NSNumber numberWithBool:valueAtKey] forKey:key];
}

两个问题。首先,当我选择第一行(全部)时出现此错误:

 由于未捕获的异常'NSGenericException'而终止应用程序,原因:'*** Collection< __ NSCFDictionary:0x597b3d0>在被列举时发生了变异。 

枚举发生在哪里?我想,因为我只选择第0行,我也可以更改其他行,而不仅仅是第0行。我不知道该怎么做。



<第二个问题是你想要更新模型类的方式吗?我不确定这是否被认为是好的MVC。谢谢。

解决方案

枚举是for循环。您可以迭代密钥的副本,以避免在枚举时改变字典:

  for(NSString * key in [ dmgr.CategoryDictionary allKeys]){
// ... ...
}


I have a filter button that presents a UITableView in a popover. I have my categories and an "All" button to denote that no filter is present like in iTunes.

I have a NSMutableDisctionary in my applicationDelegate class that I use to set the checkmarks. When the app starts, only All is selected, everything else is deselected. What I want is then when a row that is not "All" is selected, that row gets selected, and All gets deselected. Similarly, when All is selected, all the rows with checkmarks do not have checkmarks anymore, and only All is selected with a checkmark (like when the app starts). In my UITableView didSelectRowForIndexPath:, I did this:

MyAppAppDelegate *dmgr = (MyAppAppDelegate *)[UIApplication sharedApplication].delegate;
NSUInteger row = [indexPath row];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

// All selected
if (row == 0) {
    for (NSString *key in dmgr.CategoryDictionary) {
        [dmgr.CategoryDictionary setObject:[NSNumber numberWithBool:NO] forKey:key];
    }
    [dmgr.CategoryDictionary setObject:[NSNumber numberWithBool:YES] forKey:@"All"];                
}

else {

    cell.accessoryType = UITableViewCellAccessoryCheckmark;
    NSString *key = [_categoriesArray objectAtIndex:row];
    BOOL valueAtKey = [[dmgr.CategoryDictionary valueForKey:key] boolValue];
    valueAtKey = !valueAtKey;       
    [dmgr.CategoryDictionary setObject:[NSNumber numberWithBool:valueAtKey] forKey:key];
}

Two questions. First is, I get this error when I select the first row (All):

Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSCFDictionary: 0x597b3d0> was mutated while being enumerated.

Where is the enumeration happening? I thought since I only select row 0, I could change the other rows as well, and not just the row 0. I'm not sure what to do about this here.

Second question is is this the way you'd want to update your model class? I wasn't sure if this was considered good MVC. Thanks.

解决方案

The enumeration is the for-loop. You could iterate over a copy of the keys instead to avoid mutating the dictionary while enumerating it:

for (NSString *key in [dmgr.CategoryDictionary allKeys]) {
    //...
}

这篇关于收集在枚举时发生变异,UITableView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆