ios - *** 集合 <__NSArrayM : 0x117d7320> was mutated while being enumerated. '

标签 ios objective-c

我在实现搜索功能时犯了一个错误。我开了一个异步线程。但是当删除一个字符(电话号码的数字)时,应用程序会崩溃。

错误:

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

代码:

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
    //
    self.isSearch = YES;

    //remove the last search all the contacts
    [self.resultArr removeAllObjects];
    //
    [self.rcs_SearchTableView reloadData];
    //
    dispatch_queue_t uploadQueue = dispatch_get_global_queue(0, 0);
    dispatch_queue_t getMainQueue = dispatch_get_main_queue();
    dispatch_async(uploadQueue, ^{

        NSMutableArray *phoneArr = (NSMutableArray *)[self rcs_GetPhoneNumberFromeDatabaseWithPhone:searchText];
        //
        //NSLog(@"清空上次搜索的数据:%@", self.resultArr);
        //NSLog(@"输入的关键字是---%@---%lu",searchText,(unsigned long)searchText.length);
        if (0 == searchText.length || [searchText isEqualToString:@" "]) {
            self.isSearch = NO;
            //[self.rcs_SearchTableView reloadData];
            [self.resultArr removeAllObjects];
        }
        //[self.rcs_SearchTableView reloadData];

        if (0 != phoneArr.count) {
            //
            for (NSUInteger i = 0; i < phoneArr.count; i ++) {

                RCSPhoneModel *flagPhoneModel = phoneArr[i];


                for (NSUInteger i = 0; i < self.rcsRecentSearchDataSource.count; i ++) {

                    RCSContactModel *flagModel = self.rcsRecentSearchDataSource[i];

                    if ([flagPhoneModel.serverId isEqualToString:flagModel.serverId] || [flagPhoneModel.phone isEqualToString:flagModel.name]) {

                        //the same contact has multiple Numbers To prevent repeated add the same contacts
                        if (![self.resultArr containsObject:flagModel]) {

                            [self.resultArr addObject:flagModel];
                            continue;
                        }
                    }
                }
            }

        }else{
            //search contacts by name

            for (NSInteger i = 0; i < self.rcsRecentSearchDataSource.count; i ++) {
                RCSContactModel *model = self.rcsRecentSearchDataSource[i];
                NSString *nameStr = model.name;
                if (nameStr.length >= searchText.length) {
                    //search all the name
                    if ([nameStr containsString:searchText]) {
                        [self.resultArr addObject:model];
                    }
                }
            }
        }
        //
        if (self.resultArr.count > 0) {
            self.isSearch = YES;
            //[self.rcs_SearchTableView reloadData];
        }
        //The phone contacts or local contact synchronized to the server
        dispatch_async(getMainQueue, ^{

            [self.rcs_SearchTableView reloadData];
        });
    });
}

最佳答案

for 循环不应枚举任何可能在任何其他线程上更改或可能在该循环内更改的内容。您应该只枚举一个您确定在枚举时不会更改的对象(在另一个线程中,或在循环本身内)。一种方法是仅使用数组的本地副本进行枚举。

我看不到在你的 for 循环中枚举的任何东西在循环中发生了变化,所以我猜想在其他线程的一些其他代码中,你正在改变 self.rcsRecentSearchDataSourcephoneArr。这会使枚举 self.rcsRecentSearchDataSourcephoneArrfor 循环崩溃,因为它需要在枚举时不改变。

这真的需要在单独的线程上运行吗?

如果是这样,请使用数组的线程本地副本来枚举,而不是原始数组。这样你就可以确定没有其他东西可以修改它,因为它不存在于任何其他范围内。

例如,您可以在两个地方更改代码:

NSArray *localSearchDataSource = [self.rcsRecentSearchDataSource copy];

for (NSUInteger i = 0; i < localSearchDataSource.count; i ++) {

还有一个地方你可以改成:

NSArray *localPhoneArr = [[self rcs_GetPhoneNumberFromeDatabaseWithPhone:searchText] copy];

for (NSUInteger i = 0; i < localPhoneArr .count; i ++) {

关于ios - *** 集合 <__NSArrayM : 0x117d7320> was mutated while being enumerated. ',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43083550/

相关文章:

ios - Core Audio Swift Equalizer 一次调整所有频段?

objective-c - 增加 NSData 的长度

iphone - 为什么这个 View Controller 不能设置下一个 View Controller 的文本字段?

objective-c - 是否可以有一个没有启用 ARC 但有一些 arc 文件的 iOS 应用程序?

ios - UITableViewAutomaticDimension 不适用于 UIImageView

ios - 删除所选 UIButton 中的突出显示

ios - 如何将 NSstring 转换为 NSerror 对象类型

ios - 在 Xcode_6 beta 5 中只有部分 tableview 单元格内容可见

android - 如何获得有关表情符号的所有信息

objective-c - Google 云存储 objective-c 示例