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

时间:2015-01-04 07:03:50

标签: ios objective-c for-loop nsmutablearray nsarray

我已经坚持这个问题已经5个小时了。发生的事情看起来很不合逻辑,但是当我向NSMutableArray添加一个项目时,它也用它取代所有以前的项目,我不知道如何或为什么。这是EDITED代码:

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

数组中的每个项目都会更改为添加的项目。

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

1 个答案:

答案 0 :(得分:2)

让我们看一下你的代码吧,你明确表示它是“EDITED代码”,因此可能会引入一些错误 - 我们无从得知。那说:

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中的每个条目都包含一个字典, key actions指的是完全相同的数组。当您绕过循环时,清空action数组,再次填充它,您正在更改您添加的每个字典共享的数组 - 因此您看到的结果。

}

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

HTH