如果您有NSArray并且想要评估和更改元素,则无法从循环内部更改数组。因此,您创建了一个可以可以更改的可变副本。

代码示例:

NSMutableArray *bin = [NSMutableArray arrayWithObjects:@"0", @"1", @"2", @"3", @"4", @"5", @"6", @"7", nil];
NSMutableArray *list = [NSMutableArray arrayWithObjects:@"a1", @"b2", @"c3", @"e4", nil];

NSMutableArray *listHolder = list; // can't mutate 'list' within loop so create a holder

for (int i = 0; i < [list count]; i++) {
    [listHolder replaceObjectAtIndex:i withObject:[bin objectAtIndex:i]];
}

第二个数组 listHolder 被调用了什么?我的意思是,在这种情况下,用什么术语来指代数组。

有帮助吗?

解决方案

在此上下文中, listHolder 将被称为副本

你的代码有一个bug。这行实际上并没有复制,它只是让 listHolder list 都引用相同的数组对象:

NSMutableArray *listHolder = list;

这是一个实际的副本:

NSMutableArray *listHolder = [list mutableCopy];

如果您希望副本是可变的,请确保使用 mutableCopy 而不仅仅是 copy copy 方法将在所有可变类上返回不可变变量,例如 NSMutableSet NSMutableDictionary ,等等。

另外,正如其他人已经注意到,只有在 for(item in collection)循环中才能突变枚举的集合。在(;;)突变的正常中完全没问题,但如果集合中的项目数量发生变化,可能会导致奇怪的结果。

其他提示

这完全有效:

NSMutableArray *bin = [NSMutableArray arrayWithObjects:@"0", @"1", …, @"7", nil];
NSMutableArray *list = [NSMutableArray arrayWithObjects:@"a1", …, @"e4", nil];

// NSInteger should be used instead of int
for (NSInteger i = 0; i < [list count]; i++) {
    [list replaceObjectAtIndex:i withObject:[bin objectAtIndex:i]];
}

您不允许更改中的... NSEnumerate 循环中的数组,但使用索引是完全有效的。

让我感到困扰的是你对指针的误解 如果它是一个不允许变异数组的循环,则不会复制数组,只会复制指向数组的指针,从而有效地修改了不允许的数组。 (我甚至不确定这是否有效。)

而不仅仅是复制指针

// can't mutate 'list' within loop so create a holder
NSMutableArray *listHolder = list;

制作一份真实的副本:

NSMutableArray *copy = [[list mutableCopy] autorelease];

如果我真的需要复制,我会尝试根据其内容命名。例如:

NSMutableArray *views;
NSMutableArray *reorderedViews = [views mutableCopy];

// reorder reorderedViews

有时很难找到一个足够好的名字,然后我通常只使用 nameCopy

没有特定的风格或通用名称,这是普遍使用的,它是您的代码,如果适当的条款使用它们。

一般来说,如果你在这种情况下没有特定的名字,那么人们会将原始列表称为“来源”。 (src)和最终列表为“目的地” (dst),就像在内存blitting样式操作中一样。

原始NSArray的临时可变副本将是我如何引用它。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top