S.J
S.J

Reputation: 3071

Need assistance regarding NSString

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?

Upvotes: 0

Views: 81

Answers (4)

Fahri Azimov
Fahri Azimov

Reputation: 11770

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.

Upvotes: 1

Duc
Duc

Reputation: 650

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

Upvotes: 1

user3821934
user3821934

Reputation:

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.

Upvotes: 0

Viral Savaj
Viral Savaj

Reputation: 3389

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.

Upvotes: 0

Related Questions