views:

158

answers:

4

When you have an NSArray and you want to evaluate and change the elements, you can't change the array from inside the loop. So, you create a mutable copy that can be changed.

code example:

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

What is that second array listHolder called? I mean, what term is used to refer to an array in this context.

+1  A: 

There is not specific stylistic or common name for this that is universally used, it is your code afterall, and if there appropriate terms for them use them.

Having said that generally if you don't have specific names in this sort of situation then people refer to the original list as the "source" (src) and the final list as "destination" (dst), just like in a memory blitting style operation.

Louis Gerbarg
+4  A: 

This is perfectly valid:

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

You're not allowed to change the array inside a for … in or NSEnumerate loop, but using an index is perfectly valid.

What troubles me is your misunderstanding of pointers.
If it were a loop in which you weren't allowed to mutate the array this wouldn't copy the array but only the pointer to the array, effectively modifying the array you're not allowed to. (I'm not even sure if this works.)

Instead of just copying the pointer

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

make a true copy:

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

In case I really have to make a copy I try to name it according to its content. For example:

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

// reorder reorderedViews

Sometimes it's hard to find a good enough name, then I usually just use nameCopy.

Georg
This is useful information and thank you for that but you didn't answer the question. I picked a bad code example and derailed the question. At least I learned something.
willc2
+1  A: 

In this context listHolder would be called a copy.

Your code has a bug though. This line is not actually making a copy, it is only letting listHolder and list both reference the same array object:

NSMutableArray *listHolder = list;

This would be an actual copy:

NSMutableArray *listHolder = [list mutableCopy];

Make sure that you use mutableCopy and not just copy if you want the copy to be mutable. The copy method will return immutable variants on all mutable classes such as NSMutableSet, NSMutableDictionary, and so forth.

Also as others have noted it is only inside the for (item in collection) loop that the enumerated collection can not be mutated. In a normal for (;;) mutation is perfectly ok, but can lead to strange result if the number of items in the collection changes.

PeyloW
Thanks for the bug catch. I normally use (item in collection) when possible and picked a poor code example. I'm glad I did as it exposed an error in my thinking about pointers.
willc2
A: 

A temporary mutable copy of the original NSArray would be how I would refer to it.

Xetius