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];