Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

addObject in NSMutableArray is copied or retained?

When you add object into collection, such as NSMutableArray, the object is copied, that is, value semantics, or is retained, that is, reference semantics?

I am confused in the example:

NSMutableString *testStr = [@"test" mutableCopy];
NSMutableArray *arrayA = [[NSMutableArray alloc] init];

[arrayA addObject:testStr];
NSLog(@"%@", arrayA);    // output: test

testStr = [@"world" mutableCopy];
NSLog(@"%@", arrayA);    // output: test

// testStr is copied - value semantics

NSMutableArray *testArr = [@[@1, @2] mutableCopy];
NSMutableArray *arrarB = [[NSMutableArray alloc] init];

[arrarB addObject:testArr];
NSLog(@"%@", arrarB);      // output: [1, 2]

[testArr addObject:@3];
NSLog(@"%@", arrarB);      // output: [1, 2, 3]

// testArr is retained - reference semantics

You can see: if the object is a NSMutableString, it looks like the object is copied - you change the object will not affect the object in the array.

However, if the object is a NSMutableArray, when you change the object, the object in the array also be changed - like you retain the object or pass by reference.

Am I missing something here? Thanks.

like image 791
user2543991 Avatar asked Feb 20 '14 15:02

user2543991


3 Answers

Collections retain, not copy, objects that are added to them.

like image 171
Duncan C Avatar answered Oct 05 '22 12:10

Duncan C


In your first part, adding an object to the array is not making a copy. Let's look at your code:

Here you created your NSMutableString and your NSMutableArray:

NSMutableString *testStr = [@"test" mutableCopy];
NSMutableArray *arrayA = [[NSMutableArray alloc] init];

Then you add your string to the array:

[arrayA addObject:testStr];
NSLog(@"%@", arrayA);    // output: test

Next you're creating a new NSMutableString and assigning that to the variable testStr, which simply makes testStr point to the new object. It has no effect on the first string you created:

testStr = [@"world" mutableCopy];
NSLog(@"%@", arrayA);    // output: test

So that's why your first block of code works how it does.

In your second block of code, it seems that you already understand why that works how it does, but just to make it clear, testArr always points to the same array, which you also added to arrarB, hence why printing out arrarB reflects the change you make to testArr.

like image 22
Gavin Avatar answered Oct 05 '22 12:10

Gavin


String is retained too, in line:

testStr = [@"world" mutableCopy];

you create a new string and you assign its copy to the testStr local variable, so old retained string is still in the table

like image 33
Michał Banasiak Avatar answered Oct 05 '22 12:10

Michał Banasiak