集合 <__NSArrayM: 0x7fa1f2711910> 在枚举时发生了突变

Posted

技术标签:

【中文标题】集合 <__NSArrayM: 0x7fa1f2711910> 在枚举时发生了突变【英文标题】:Collection <__NSArrayM: 0x7fa1f2711910> was mutated while being enumerated 【发布时间】:2015-09-30 12:09:19 【问题描述】:

有很多类似标题的问题,但没有一个对我有帮助。

但我可以将这个'NSGenericException', reason: Collection <__NSArrayM: 0x7fabb400> was mutated while being enumerated 的解决方案联系起来 我的问题。 因为这种终止正在发生 当我添加时,用数组删除字符串对象。

错误:

由于未捕获的异常“NSGenericException”而终止应用程序, 原因:'*** Collection <__nsarraym:> 在枚举时发生了变异。'

第一次抛出调用栈:

(

0   CoreFoundation                      0x00000001087b8c65 __exceptionPreprocess + 165
1   libobjc.A.dylib                     0x0000000108422bb7 objc_exception_throw + 45
2   CoreFoundation                      0x00000001087b85c4 __NSFastEnumerationMutationHandler + 132
3                                       0x0000000107e24cf5 -[ProfessionalRegSecond tableView:didDeselectRowAtIndexPath:] + 773
4   UIKit                               0x0000000109759d71 -[UITableView _deselectRowAtIndexPath:animated:notifyDelegate:] + 347
5   UIKit                               0x000000010974deea -[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 187
6   UIKit                               0x000000010968062c _applyBlockToCFArrayCopiedToStack + 314
7   UIKit                               0x00000001096804a6 _afterCACommitHandler + 533
8   CoreFoundation                      0x00000001086ebca7 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
9   CoreFoundation                      0x00000001086ebc00 __CFRunLoopDoObservers + 368
10  CoreFoundation                      0x00000001086e1a33 __CFRunLoopRun + 1123
11  CoreFoundation                      0x00000001086e1366 CFRunLoopRunSpecific + 470
12  GraphicsServices                    0x000000010d6c8a3e GSEventRunModal + 161
13  UIKit                               0x000000010965c900 UIApplicationMain + 1282
14                                      0x0000000107de14cf main + 111
15  libdyld.dylib                       0x000000010b585145 start + 1
)

libc++abi.dylib:以 NSException 类型的未捕获异常终止

我想要做什么:

我需要这样的数组,当我选择单元格时,我想将该对象添加到数组中,当我取消选择行时,我想从数组中删除该行,因此结果数组将仅是选定的条目。如何做到这一点?

这是我的代码

@implementation Professional

    
         NSMutableArray *updatedLocalityArray; // alloc,init did in viewDidLoad
         NSString *toCheck;
    

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

   

        UITableViewCell *tableViewCell = [tableView cellForRowAtIndexPath:indexPath];

        NSLog(@"%@",tableViewCell.textLabel.text);

        toCheck = tableViewCell.textLabel.text;
        [updatedLocalityArray addObject:toCheck];
        NSLog(@"%@ *****", updatedLocalityArray);

   

  - (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
    

        UITableViewCell *tableViewCell = [tableView cellForRowAtIndexPath:indexPath];
           NSLog(@"%@",tableViewCell.textLabel.text);

        for (NSString *test in updatedLocalityArray)
        
            if ([test isEqualToString:tableViewCell.textLabel.text])
            

                [updatedLocalityArray removeObject:test];
                NSLog(@"%@ *****", updatedLocalityArray);

            

        

    

【问题讨论】:

【参考方案1】:

您无法在迭代 NSMutableArray 时删除项目。

有几种解决方案:

迭代数组的副本

使用基于索引的for 循环而不是for each 语法。

不复制数组可以节省分配和一些 CPU 周期:

for (int i = updatedLocalityArray.count-1 ; i >= 0 ; i--)

    NSString *test = updatedLocalityArray[i];
    if ([test isEqualToString:tableViewCell.textLabel.text])
    
        [updatedLocalityArray removeObjectAtIndex:i];
        NSLog(@"%@ *****", updatedLocalityArray);
    

【讨论】:

谢谢你..!向你的声誉致敬.. 太棒了!【参考方案2】:

在您的 tableview 取消选择方法中,您写道:

for (NSString *test in updatedLocalityArray)

    if ([test isEqualToString:tableViewCell.textLabel.text])
    
        [updatedLocalityArray removeObject:test];
        NSLog(@"%@ *****", updatedLocalityArray);
    

在该代码中,您通过updatedLocalityArray 进行枚举,如果您找到匹配项,您将从同一个数组中删除该对象,此逻辑会导致此处出现问题。为了解决这个问题,您需要创建本地副本并在其中进行更改,并在枚举后将其分配回原始数组。

NSMutableArray *tempArray = [updatedLocalityArray mutableCopy];
for (NSString *test in updatedLocalityArray)

    if ([test isEqualToString:tableViewCell.textLabel.text])
    
        [tempArray removeObject:test];
        NSLog(@"%@ *****", tempArray);
    

updatedLocalityArray = tempArray;

【讨论】:

【参考方案3】:

如果你当前的数组是A,你可以复制另一个同样的数组叫B,然后你可以枚举B并操作A,就不会崩溃了。

枚举时不能修改容器。

NSMutableArray *tempArray = someArray.mutableCopy;

【讨论】:

【参考方案4】:

如果你当前的数组是A,你可以复制另一个相同的数组B,然后你可以枚举B并操作A,就不会崩溃了。

【讨论】:

重复的答案,完全复制自另一个答案。 -1【参考方案5】:

在使用for...in... 控制语句循环遍历数组时,您无法修改该数组。

试试:

    NSArray *compareArray = [updatedLocalityArray copy];
    for (NSString *test in compareArray)
    // ...

【讨论】:

以上是关于集合 <__NSArrayM: 0x7fa1f2711910> 在枚举时发生了突变的主要内容,如果未能解决你的问题,请参考以下文章

当我在 Swift 中打印一个数组时,它的类型(<__NSArrayM 0x60800024a1a0>)也随之而来。为啥?

如何提取 __NSArrayM 中的每个元素?

无法将“__NSArrayM”类型的值转换为“NSDictionary”

NSArrayM 在枚举时发生了突变

[__NSArrayM objectAtIndex:]: 索引 9223372036854775807 超出范围 [0 .. 13]'

异常'NSRangeException',原因:'*** -[__NSArrayM objectAtIndex:]:索引 19 超出范围 [0 .. 18]'