addObjectsFromArray不会将它们添加为新对象

时间:2013-11-12 21:45:50

标签: ios arrays

我的问题是当我使用对象复制数组时,似乎如果我更改复制的数组,原始数组也会更改。下面是我的代码的简化版本。

我有一个对象数组

@interface TimesViewController (){
    NSMutableArray *route1;
}

我在ViewDidLoad方法中填写这些对象

route1 = [[NSMutableArray alloc] init];

while (sqlite3_step(statement) == SQLITE_ROW) {       

    StopsOnRoutes *stopOnRoutes = [[StopsOnRoutes alloc] init];

    [stopOnRoutes setStart_time:p_time];
    [stopOnRoutes setStart_route_id:p_route];
    [stopOnRoutes setStart_stop_id:p_stop];
    [stopOnRoutes setStop_time:c_time];
    [stopOnRoutes setStop_route_id:c_route];
    [stopOnRoutes setStop_stop_id:c_stop];
    [stopOnRoutes calc];

    [route1 addObject:stopOnRoutes];
}

但是当我尝试复制route1并进行一些更改时,它们会在route1和amTimes中同时更改

NSMutableArray *amTimes = [[NSMutableArray alloc] init];
[amTimes addObjectsFromArray:route1];

for(int i = 0; i<amTimes.count; i++){
    [[amTimes objectAtIndex:i] setStop_time:[[amTimes objectAtIndex:i] stop_time]-86400];
    [[amTimes objectAtIndex:i] setStart_time:[[amTimes objectAtIndex:i] start_time]-86400];
}

如何将route1复制到amTimes,因此如果我在AM时间更改一个对象,它将不会在route1中更改。

4 个答案:

答案 0 :(得分:2)

数组的工作方式只是保存数组中对象的引用(指针)。因此,当您添加对象时,它不会创建新对象并指向它,它只是指向该对象。你想要做的是被称为深拷贝数组,它涉及处理数组中的每个对象。

使用

时会发生什么
- (instancetype)initWithArray:(NSArray *)array copyItems:(BOOL)flag

数组中的每个对象都发送一个copyWithZone,你可以在你想要添加到数组的每个对象中实现copyWithZone,然后再做

[myArray addObject[myObject copy]];

或者您也可以使用

[[NSArray alloc] initWithArray:otherArray copyItems:YES] //You need to implement copyWithZone in the items you want to copy.

这将为您提供所需的结果。

答案 1 :(得分:1)

您需要让StopOnRoutes类实现NSCopying协议和copyWithZone:方法。此方法需要创建self

的副本

然后你可以这样做:

NSMutableArray *amTimes = [[NSMutableArray alloc] init];
for (StopOnRoutes *obj in route1) {
    [amTimes addObject:[obj copy]];
}

答案 2 :(得分:0)

容器对象不包含添加到它们的对象的副本,它们包含指向对象的指针。如果将同一对象添加到2个数组,则它是两个数组的成员。

如果要创建副本数组,则需要执行以下操作:

您需要为阵列中的对象实现NSCopying协议,以便您可以复制它们。

然后你需要创建一个新的可变数组,其中包含与第一个数组相同数量的元素的空间,遍历第一个数组,复制每个项目,并将其添加到第二个数组。

如果您的数组仅包含支持NSCopying的标准系统对象,那么您的工作会更简单。如果您的数组包含不同类型的自定义对象或复杂的自定义对象,那么您可能还有更多工作要做。

答案 3 :(得分:-1)

尝试使用setArray:即[amTimes setArray:route1];