0

In NSString NSString Class Reference what this means

Distributed objects:
Over distributed-object connections, mutable string objects are passed by-reference and immutable string objects are passed by-copy.

And NSString can't be changed, so what happening when I am changing str in this code

NSString *str = @"";
for (int i=0; i<1000; i++) {
    str = [str stringByAppendingFormat:@"%d", i];
}

will I get memory leak? Or what?

S.J
  • 3,063
  • 3
  • 33
  • 66

4 Answers4

1

What your code is doing:

NSString *str = @""; // pointer str points at memory address 123 for example
for (int i=0; i<1000; i++) {
    // now you don't change the value to which the pointer str points
    // instead you create a new string located at address, lets say, 900 and let the pointer str know to point at address 900 instead of 123
    str = [str stringByAppendingFormat:@"%d", i]; // this method creates a new string and returns a pointer to the new string! 

    // you can't do this because str is immutable
    // [str appendString:@"mmmm"];
}

Mutable means you can change the NSString. For example with appendString.

pass by copy means that you get a copy of NSString and you can do whatever you want; it does not change the original NSString

- (void)magic:(NSString *)string
{
    string = @"LOL";
    NSLog(@"%@", string);
}

// somewhere in your code
NSString *s = @"Hello";
NSLog(@"%@", s); // prints hello
[self magic:s];  // prints LOL
NSLog(@"%@", s); // prints hello not lol

But imagine you get a mutable NSString.

- (void)magic2:(NSMutableString *)string
{
    [string appendString:@".COM"];
}

// somewhere in your code
NSString *s = @"Hello";
NSMutableString *m = [s mutableCopy];
NSLog(@"%@", m); // prints hello
[self magic2:m];
NSLog(@"%@", m); // prints hello.COM

Because you pass a reference you can actually change the "value" of your string object since you are working with the original version and not a duplicate.

NOTE String literals live as long as your app lives. In your exmaple it means that your NSString *str = @""; never gets deallocated. So in the end after you have looped through your for loop there are two string objects living in your memory. Its @"" which you cannot access anymore since you have no pointer to it but it is still there! And your new string str=123456....1000; But this is not a memory leak.

more information

Community
  • 1
  • 1
Duc
  • 650
  • 5
  • 10
  • if str gets new copy then old one will be without reference, so didn't I get memory leak? – S.J Apr 17 '15 at 06:49
  • no because your old string will get removed. your old string lives as long as your „for loop“ has not stepped further. – Duc Apr 17 '15 at 06:52
  • but what if I am using non-ARC. – S.J Apr 17 '15 at 07:05
  • Sorry i was mistaken. String literals like NSString *s = @"string" live as long you app lives! I edited my answer. – Duc Apr 17 '15 at 07:16
  • If I can't access an object any more means I have lost its reference, still why it is not an memory leak? – S.J Apr 17 '15 at 07:51
  • because you never allocate memory for your string. it is already reserved by the os before you start your app. – Duc Apr 17 '15 at 08:14
1

No, you will not get memory leak with your code, as you are not retaining those objects in the loop, they're created with convenience method, you don't own them, and they will be released on next cycle of autorelease pool. And, it's doesn't matter if you are using ARC or not, objects created with convenience methods and not retained are released wherever they are out of their context.

Fahri Azimov
  • 11,470
  • 2
  • 21
  • 29
0

In will not leak memory, but will get more memory allocation, due to making new copy of immutable copy as many time loop triggers [str stringByAppendingFormat:@"%d", i];.

Memory leak will get performed when, you put your data unreferenced, or orphan, this will not make your last copy of string orphan every time when loops, but will clear all copies of NSString when operation get complete, or viewDidUnload.

Viral Savaj
  • 3,379
  • 1
  • 26
  • 39
  • if str gets new copy then old one will be without reference, so didn't I get memory leak? – S.J Apr 17 '15 at 06:44
0

You will not get a memory leak in the example code because Automatic Reference Counting will detect the assignment to str and (automatically) release the old str.

But it would be much better coding style (and almost certainly better performance) to do this:

NSMutableString* mstr = [NSMutableString new];
for(int i = 0; i < 1000; ++i){
    [mstr appendFormat:@"%d",i];
}
NSString* str = mstr;
...

As to the first question, I think it means that a change made to a mutable string by a remote process will be reflected in the originating process's object.

  • if str gets new copy then old one will be without reference, so didn't I get memory leak? – S.J Apr 17 '15 at 06:48