7

Given the following code example, is the newMutableArrray variable different depending on the two different initializations, or the same?

NSArray *originalArray = @[obj1, obj2, oj3];

NSMutableArray *newMutableArray = nil;

if (thereIsSomeDifference) {  
    newMutableArray = [NSMutableArray arrayWithArray:originalArray];  
}  
else {  
    newMutableArray = [originalArray mutableCopy];  
} 
2
  • What is thereIsSomeDifference? Commented Jan 6, 2013 at 20:35
  • thereIsSomeDifference is the hypothetical condition for which I would want to initialize newMutableArray one or the other way. This is the essence of the question, because if there is no difference, as your answer indicates, the thereIsSomeDifference condition does not exist. Commented Jan 6, 2013 at 20:46

4 Answers 4

15

NO !!! There is two differences between these initializations :

  1. Retain count: in the first case, you get an autoreleased object, in the second case, you get a retained object, you will need to release it after (This doesn't apply on ARC)

  2. If originalArray is nil, in the first case, you will get a mutable array with 0 item, in the second case, you will get nil (because sending a message to nil returns nil). In your example, it is clear that originalArray is not nil but in real life you can reach this case (I just had the case)

Sign up to request clarification or add additional context in comments.

Comments

7

An array is equal to another array (isEqualToArray: selector) if they have the same objects (in the same order). This is verified using the isEqual: method (disregarding of the array being mutable or not).

They're just the same, one or another initialisation doesn't make any difference. Verify this logging the result of isEqualToArray: .

NSArray *originalArray = @[obj1, obj2, oj3];
NSMutableArray *newMutableArray = nil;
newMutableArray = [NSMutableArray arrayWithArray:originalArray];  
thereIsSomeDifference= ![newMutableArray isEqualToArray: [originArray mutableCopy] ];

Notice that the comparison would be true even if you compared it with a non-mutable copy.

3 Comments

Thanks for editing to provide additional explanation. Great answer.
You should clarify that two arrays are equal if the objects inside are the same and the objects are in the same order too.
Note: If originalArray is nil, [NSMutableArray arrayWithArray:originalArray] will return an empty NSMutableArray whereas [originalArray mutableCopy] will return nil.
1

No, the result of them is exactly the same.
Only the initialisation is different

2 Comments

Thanks for your answer. I accepted @Ramy Al Zuhouri's answer only because it appeared before yours.
@seeker12 Mine was first actually, but it doesn't matter, his answer was better.
1

In order to answer, we have to define "sameness". The two inits side by side will result in different collections, but they will be the same insofar as they point to the same elements.

In other words:

initA = [NSMutableArray arrayWithArray:originalArray];  
initB = [originalArray mutableCopy];

if (initA == initB) {
   // unreachable, because the pointers differ
}

// however
if ([initA isEqualToArray:initB]) {
   // will be true
   // because
   for (int i=0; i<initA.count; i++) {
       if ([initA objectAtIndex:i] == [initB objectAtIndex:i]) {
           NSLog(@"this will log every element %@ in the arrays", [initA objectAtIndex:i]);
       }
   }
}

3 Comments

I suppose "sameness" would be defined as "... they point to the same elements". In what way would the two collections differ?
As I indicated, they would fail a deep equality test a == b.
Ah, ok. I was confused, as my example initializes a single variable one of two ways, based on some condition, and not "...two inits side by side...". Good point. Thanks for the additional explanation.

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.