关于在Objective-C中通过NSArray进行循环的术语问题
-
07-07-2019 - |
题
如果您有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的临时可变副本将是我如何引用它。