for 循环将最新项目重新添加到 NSMutableArray iOS 中的所有先前位置

for loop re-adds latest item to all previous positions in NSMutableArray iOS

我已经在这个问题上卡了 5 个小时了。发生的事情看起来很不合逻辑,但是当我将一个项目添加到 NSMutableArray 时,它也会用它替换所有以前的项目,我不知道如何或为什么。这是编辑后的代码:

NSMutableArray* action = [[NSMutableArray alloc]init];
BackendlessDataQuery *query = [BackendlessDataQuery query];

for (int i = 0; i<self.categoryNames.count; i++) 
{

    query.whereClause = [NSString stringWithFormat:@"category = \'%@\'", self.categoryNames[i]];
    BackendlessCollection *collection = [backendless.persistenceService find:[ActionCreation class] 
                                                                   dataQuery:query];
    [action removeAllObjects];
    for (int j=0; j<collection.data.count; j++) 
    {
        NSDictionary *dictionaryToInsert = @{ 
                       @"nameAction"  : [collection.data[j] nameAction],
                       @"nameCompany" : [collection.data[j] nameCompany],
                       @"action_start": [collection.data[j] action_start],
                       @"action_end"  : [collection.data[j] action_end],
                       @"address"     : [collection.data[j] adress]     };
        [action insertObject:dictionaryToInsert atIndex:j];
    }
    //NSLog(@"CAtegory Actions %@", action);

    [self.sampleData insertObject: @{   @"category": self.categoryNames[i],
                                        @"actions" : action                 }.mutableCopy                 
                          atIndex:i];

     //NSLog(@"Categories %@", self.sampleData);

}
NSLog(@"-------------------------------");
NSLog(@"sampleData %@", self.sampleData);

之后
[self.sampleData insertObject:@{ @"category": self.categoryNames[i],
                                 @"actions" : action                 }.mutableCopy 
                      atIndex:i]; 

数组中的每一项都更改为添加的一项。

输出显示数组中的所有项目都是相同的,并且是最新添加的。感谢您的帮助。

让我们看看您的代码,您清楚地表明它是 "EDITED code",因此可能会引入一些错误 - 我们无从知晓。也就是说:

NSMutableArray* action = [[NSMutableArray alloc]init];

在这里创建一个新的空可变数组action

BackendlessDataQuery *query = [BackendlessDataQuery query];

for (int i = 0; i<self.categoryNames.count; i++) {

query.whereClause = [NSString stringWithFormat:@"category = \'%@\'", self.categoryNames[i]];
BackendlessCollection *collection = [backendless.persistenceService find:[ActionCreation class] dataQuery:query];

    for (int j=0; j<collection.data.count; j++) {

你循环了很多次...

        [action removeAllObjects];

每次清空 action...

         NSDictionary *dictionaryToInsert = @{ @"nameAction"  : [collection.data[j] nameAction],
                       @"nameCompany" : [collection.data[j] nameCompany],
                       @"action_start": [collection.data[j] action_start],
                       @"action_end"  : [collection.data[j] action_end],
                       @"address"     : [collection.data[j] adress]};
        [action insertObject:dictionaryToInsert atIndex:j];

然后尝试向其中添加项目。

在您的代码的这个版本中,这将在第二次迭代时失败,因为您不能在现有索引或超过最高索引的索引以外的任何地方使用 insertObject:atIndex:。当您在每次迭代中清空数组时,唯一有效的索引是 0,因此在索引为 1 的第二次迭代中,您将得到一个异常。

您可能不打算在每次迭代时清空数组。此外,您只需使用 addObject: 来填充 action.

会更简单
    }
    [self.sampleData insertObject:[@{@"category": self.categoryNames[i],
                                     @"actions" : action} mutableCopy] atIndex:i];

在这里你将 action 添加到一个字典,制作该字典的可变副本,然后添加 self.sampleData.

方法mutableCopy(和copy)对一个对象进行浅拷贝——你得到的是一个新字典,但是字典本身是不是自己复制的。

因此您的副本还包含对与 self.categoryNames[i]action 相同对象的引用,这反过来意味着 每个 条目 self.sampleData 包含一个字典,其键 actions 引用 完全相同的 数组。当你绕过你的循环时,清空 action 数组,再次填充它你正在改变你添加的每个字典共享的数组 - 因此你看到的结果。

}

要修复您的代码,您应该将 action 的声明移到第一个循环内,删除 removeAllObjects,并删除 mutableCopy。这样您将为每个集合创建一个新数组,填充它,并将其添加到 self.sampleData。 (您也可以切换到使用 addObject:,但这不是必需的。)

HTH