Question

So I've been programming for a year but this concept still trips me up sometimes. My understanding is that if you don't initialize and allocate a new object when you create a new variable name using the pointer operator '*' that the danger is that the value of that new variable will always just be tied to whatever memory address it is you've pointed the name. For example, in #2 if string is set to '6' because array[1] is set to '6' but later the value of element #1 in array changes to '7' then string will return 7. But if I used method 1 where I use a string class method to allocate and initialize a memory address of its own for string then string would stay '6' even if later element #1 is changed to hold a value of '7'. Is this right?

What’s the difference between:

NSString *string = [NSString stringwithstring: array[1]];

AND

NSString *string =  array[1];

As a sidenote: I have a tough time understanding how this will matter much because if array is immutable then the only way it could be changed is if a new array is initialized and reallocated with a different value for element #1. Also, once my view controller gets popped off of the stack when the user continues to navigate through my app, if it gets called again all of these objects will get recreated from scratch- so it usually won't matter. But I just want to make sure I am getting the concept anyways.

Was it helpful?

Solution

Actually, whether you use the 1st or 2nd option has nothing to do with the array itself.

The 2nd option would not result in any change even if the array was mutable and you replaced the object at index 1. string would still point to the original object.

In the example you've given, the choice of the two options only matters if in reality, the string you get from the array is an NSMutableString. If the string is an immutable NSString then either option gives the same result. But if you actually have a mutable NSMutableString, then option 2 means that your string value can change over time of another reference to the mutable string makes changes to the string.

Example:

NSMutableString *mutable = [NSMutableString stringWithString:@"hello"];
NSArray *array = @[ @"stuff", mutable ];
NSString *string1 = [NSString stringWithString:array[1]];
NSString *string2 = array[1];
NSLog(@"string1 = %@, string2 = %@", string1, string2);
[mutable appendString:@" there"];
NSLog(@"string1 = %@, string2 = %@", string1, string2);

The log output will be:

string1 = hello, string2 = hello
string1 = hello, string2 = hello there

See how string2 was changed as a result of modifying mutable.

OTHER TIPS

(edit: per martin R's comment--suppose the strings in the example are mutable strings)

I made a diagram to help explain what's going on.

The first diagram is your initial setup. string = nil and you have a string reference in array[1].

1) do string = array[1]. Now string and array[1] point to the same string object.

2a) alternately, as in 2a, you can do string = [ NSString stringWithString:array[1]]... This will point string to a copy of the string in array[1]

Notice in all cases if you mutate the array, string still contains a reference to either a) the original string from array[1] or the copy you created.

2b) For example, let's do array[1] = @"test". [string description] will still return ABC

HTH


enter image description here

Your string pointer does not remember where the string was at the time you assigned it, so array-level changes don't matter.

The practical difference is about what happens if your array actually contains mutable strings instead of plain ones. Your first example creates a new string that has the content that's at array[1] when the assignment takes place. In your second example, the thing pointed to by string could be different moment-to-moment if some other code changed the underlying mutable string that's in array[1] at assignment time.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top