Objective c 如何修复此错误:集合<__NSDictionaryM:0x6000005ab3a0>;在被枚举时是否发生了变异?

Objective c 如何修复此错误:集合<__NSDictionaryM:0x6000005ab3a0>;在被枚举时是否发生了变异?,objective-c,uitableview,error-handling,Objective C,Uitableview,Error Handling,我有一个包含多个部分的表视图。允许在每个部分中只选择一个项目,当用户单击任何项目时,将取消选择下一部分中的所有选定项目 有时,当用户单击某个项目时,我会出错。这并不总是发生 这是我的密码 @property(nonatomic,strong) NSMutableDictionary *selectionData; -(void)handleSelectionForSection:(long)sectionIndex row:(long)rowIndex { if ([self.se

我有一个包含多个部分的表视图。允许在每个部分中只选择一个项目,当用户单击任何项目时,将取消选择下一部分中的所有选定项目

有时,当用户单击某个项目时,我会出错。这并不总是发生

这是我的密码

@property(nonatomic,strong) NSMutableDictionary *selectionData;


-(void)handleSelectionForSection:(long)sectionIndex row:(long)rowIndex
{

    if ([self.selectionData objectForKey:[NSString stringWithFormat:@"%ld",sectionIndex] ] != nil) {

        NSMutableArray *sectionData=[[self.selectionData objectForKey:[NSString stringWithFormat:@"%ld",sectionIndex]] mutableCopy];

        if (![sectionData containsObject:[NSNumber numberWithLong:rowIndex]])
        {
            // cell is not selected before (new cell selection)
            //removing previous selected rows from the same section
            [sectionData removeAllObjects];
            [sectionData addObject:[NSNumber numberWithLong:rowIndex]];

            [self.selectionData setObject:sectionData forKey:[NSString stringWithFormat:@"%ld",sectionIndex]];
        }
        else
        {
            //cell you tapped is already selected,
            // you can deselect it by removing object

            //if you dont want to deselect it comment following lines
            //[sectionData removeObject:[NSNumber numberWithLong:rowIndex]];

            [self.selectionData setObject:sectionData forKey:[NSString stringWithFormat:@"%ld",sectionIndex]];
        }
    }
    else
    {
        //section key not available so we need to create it
        NSMutableArray *sectionData=[[NSMutableArray alloc]init];
        [sectionData addObject:[NSNumber numberWithLong:rowIndex]];

        [self.selectionData setObject:sectionData forKey:[NSString stringWithFormat:@"%ld",sectionIndex]];

    }



    // todo: remove all rows in the next sections


    for (id key in self.selectionData) {
        // loop all next sections and deselect their rows
        if ([key intValue] > sectionIndex) {
            // this section comes after the current section
            // deselect
            [self.selectionData removeObjectForKey:key];

        }
    }
    NSLog(@"All Selection : %@",self.selectionData);
    NSLog(@"%@", self.selectionData);

}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    [self handleSelectionForSection:indexPath.section row:indexPath.row];

...
}

错误

2020-06-07 17:05:38.051339+1000******[69042:2401980]***由于未捕获的异常“NSGenericeException”而终止应用程序,原因:“***集合在枚举时发生了变异。”
***第一次抛出调用堆栈:
(
0 CoreFoundation 0x000000010ab6f8db例外预处理+331
1 libobjc.A.dylib 0x0000000109cd4ac5 objc_异常_抛出+48
2 CoreFoundation 0x000000010ab6c7ac\uu NSFastEnumerationMutationHandler+124
3*******0x000000010445c267-[SMGuidelinesSubProductsListViewController手柄选择:行:][1767
4*********0x000000010445c4fa-[SMGuidelinesSubProductsListViewController表视图:DIDSelectRowatineIndexPath:+170
5*********0x0000000104657352-[SMTableDisposer tableView:DidSelectRowatineIndexPath:+578
6 UIKitCore 0x0000000113f6ad4d-[UITableView\u selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:+1810
7 UIKitCore 0x0000000113f6af61-[UITableView\u用户选择RowatPendingSelectionIndexPath:+337
8 UIKitCore 0x0000000113d580e9\u在CACommitDeferredBlocks+318之后运行
9 UIKitCore 0x0000000113d475b9\u在CAFLUSHANDRUNDERDERREDBLOCKS+358之后进行清理
10 UIKitCore 0x0000000113d74923\u在CACommithandler+124之后
11 CoreFoundation 0x000000010aad62c7\uuuu CFRUNLOOP\u正在调用\u OUT\u以调用\u观察者\u回调函数\uuuu23
12 CoreFoundation 0x000000010aad078e\uuu cfrunloopdoobserver+430
13 CoreFoundation 0x000000010aad0e01\uuu CFRunLoopRun+1505
14 CoreFoundation 0x000000010aad04d2 CFRunLoopRunSpecific+626
15图形服务0x000000010f08c2fe GSEventRunModal+65
16 UIKitCore 0x0000000113d4cfc2 UIApplicationMain+140
17**********0x00000001044cb230干管+112
18 libdyld.dylib 0x000000010b5b8541开始+1
19°?0x0000000000000001 0x0+1
)
libc++abi.dylib:以NSException类型的未捕获异常终止
(lldb)
今后如何防止此错误?


谢谢

请尝试理解错误消息

NSDictionaryM:0x6000005ab3a0>在枚举时发生了变异

在循环
for(id key In self.selectionData){}
中,您正在执行错误消息所说的操作:在枚举时从字典中删除项目,这是非常不鼓励的

更可靠的解决方案是使用谓词过滤键,并同时删除所有键/值对

替换

for (id key in self.selectionData) {
    // loop all next sections and deselect their rows
    if ([key intValue] > sectionIndex) {
        // this section comes after the current section
        // deselect
        [self.selectionData removeObjectForKey:key];

    }
}

NSPredicate*谓词=[NSPredicate predicateWithFormat:@“SELF.intValue>%d”,sectionIndex];
NSArray*filteredKeys=[self.selectionData.allKeys FilteredArray使用谓词:谓词];
[self.selectionData RemoveObjects标记:filteredKeys];

请尝试理解错误消息

NSDictionaryM:0x6000005ab3a0>在枚举时发生了变异

在循环
for(id key In self.selectionData){}
中,您正在执行错误消息所说的操作:在枚举时从字典中删除项目,这是非常不鼓励的

更可靠的解决方案是使用谓词过滤键,并同时删除所有键/值对

替换

for (id key in self.selectionData) {
    // loop all next sections and deselect their rows
    if ([key intValue] > sectionIndex) {
        // this section comes after the current section
        // deselect
        [self.selectionData removeObjectForKey:key];

    }
}

NSPredicate*谓词=[NSPredicate predicateWithFormat:@“SELF.intValue>%d”,sectionIndex];
NSArray*filteredKeys=[self.selectionData.allKeys FilteredArray使用谓词:谓词];
[self.selectionData RemoveObjects标记:filteredKeys];

出于某种原因,它正在删除所有内容。它应该删除[key:value],其中只有key>section索引按预期过滤键。我在筛选之前测试了代码:self.selectionData=@“2”:0之后:self.selectionData:0键/值对可能是因为键是字符串?是的,确实,我假设键是
NSNumber
对象。请查看编辑。出于某种原因,它正在删除所有内容。它应该删除[key:value],其中只有key>section索引按预期过滤键。我在筛选之前测试了代码:self.selectionData=@“2”:0之后:self.selectionData:0键/值对可能是因为键是字符串?是的,确实,我假设键是
NSNumber
对象。请看编辑。
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.intValue > %d", sectionIndex];
NSArray<NSString *> *filteredKeys = [self.selectionData.allKeys filteredArrayUsingPredicate: predicate];
[self.selectionData removeObjectsForKeys:filteredKeys];