4

I've read through many SO posts before asking this question and I'm guessing this answer was in there somewhere, but I didn't see it. I'm new to Objective-C and I'm trying to do a (seemingly) simple action that I can't figure out.

The general idea is that I have an NSArray filled with objects (specifically of type UIImageView). I want to copy that array, which I've done a number of ways (all successful).

After a copy it, I now have two arrays. I want to modify an object, say at index 2, ONLY in the copy.

So far it seems like, because the copy is merely copying the reference (or pointer), changing the object at index 2 will change it in both the copy and the original.

Does that make sense?

NSArray *originalArray = @[object1, object2];

Ways I've tried copying this array, so that I can achieve what I want:

NSMutableArray *originalArrayCopy = [NSMutableArray arrayWithArray:originalArray];

NSArray *originalArrayCopy = [originalArray copy];

NSMutableArray *originalArrayCopy = [[NSMutableArray alloc] initWithArray:originalArray];

And it seems that in each case, modifying an object from the copy also modifies it in the original.

NOTE: While NSArray is obviously immutable, the objects within my original array are mutable.

4 Answers 4

13

If the elements of your array conform to the NSCopying protocol, you can do this:

NSMutableArray *copy = [[NSMutableArray alloc] initWithArray:originalArray copyItems:YES];

This has the effect of sending copy to each element of the original array, storing the copies in the new array.

This is fine if each element returns a new, mutable copy when it receives the copy message. However, several Foundation classes (like NSMutableArray and NSMutableString) return immutable copies when they receive the copy message. If your elements belong to such a class, you need to send the mutableCopy message instead.

There's no built-in public message to do that. You can do it manually like this:

NSMutableArray *copy = [[NSMutableArray alloc] initWithCapacity:originalArray.count];
for (id element in originalArray) {
    [copy addObject:[element mutableCopy]];
}
Sign up to request clarification or add additional context in comments.

5 Comments

Yes, that second solution makes sense. I made a mistake in my question, however, because I didn't specify that the elements in my original array are of type UIImageView. I know that makes things a bit more challenging. When trying out the second solution, I receive the error: NSInvalidArgumentException [UIImageView mutableCopywithZone:]
Each of the UIImageView objects is a property of one of my classes.
Please edit your question to explain why you want to copy the image views. Where will you put them in your view hierarchy?
Yes, thanks. While my question still applies, the way I "needed" to copy instances of UIImageView was just a design flaw on my part.
second solution worked for me.but i still hv one doubt that y it doesnt work when we use NSMutableArray*copy=[originalArray mutableCopy];
1

This makes a deep copy of the first NSArray into a Second NSMutableArray:

NSArray *firstArray = [NSArray arrayWithObjects:@"foo", @"bar",nil];
NSMutableArray *secondArray = [[NSMutableArray alloc]initWithArray:firstArray copyItems:YES];

Comments

1

As long as objects you're going to copy implement the NSCoding protocol

(void)encodeWithCoder:(NSCoder *)encoder;
(id)initWithCoder:(NSCoder *)decoder;

you could make a deep copy of any object in this way

NSArray *originalArray = @[object1, object2];
NSMutableArray *deepCopy = [NSkeyedUnarchiver unarchiveObjectWithData: [NSKeyedArchiver archivedDataWithRootObject: originalArray]];

Comments

0

Yes, all that would copy the array only. Your copied array will still refer to the same objects.

I don't think (or just don't know how) that you can copy all contained objects in one go. I guess that you would have to iterate through the objects in the original array, copy each object and add its copy to a newly created and originally empty mutable array. How these objects are to be copied depends very much on the nature of these objects and on the purpose for copying them.

And yes, there is no reason why the objects within an immutable array should be immutable too.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.