NSString vs NSMutableString with stringByAppendingString

So, I'm sure that if I plan to manipulate strings frequently, for example with stringByAppendingString , I should use variables like NSMutableString.

But what if I do something like this?

 UILabel *someLabel = [[UILabel alloc] init]; [someLabel setText: [[someDictionary objectForKey:@"some_key"] stringByAppendingString:@"some other string"]; 

I read that if you use stringByAppendingString in an NSString, you will get leaks because the pointer associated with the initial NSString moves to point to the new line created by append, whereas with NSMutableString your pointer always points to this mutable string.

So my question is: what implicitly happens when I call stringByAppendingString on what is a string, but obviously not an NSString or NSMutableString? For example, in my case above, the value of some key in the dictionary. Does it wrong, and should I do something like below?

 [[[NSMutableString stringWithString:[someDictionary objectForKey:@"some_key"]] stringByAppendingString:@"some other string"]] 
+4
source share
4 answers

I have always been a fan of [NSString stringWithFormat@ "%@%@", a, b]; , because then you obviously get a new line with auto-implementation and you can correctly dispose of "a" and "b".

With [someDictionary objectForKey:@"some_key"] you get the type of object that was originally placed in this dictionary. Therefore, blindly calling stringByAppendingString without knowing what seems like a bad idea in this dictionary.

+3
source

I read that if you use stringByAppendingString on an NSString, you get leaks because the pointer associated with the initial NSString moves to point to the new line created by add, whereas with NSMutableString, your pointer always points to this mutable string.

This sounds like advice from someone who doesn't quite understand what is happening with memory management. Of course, [NSString stringByAppendingString] returns a new string. But what you do with this new line is up to you. You could, of course, cause a memory leak by reassigning the result to the stored property in a carefree manner, for example:

 myStringProperty = [myStringProperty stringByAppendingString:@" more bits"]; 

The correct form would be to use self, for example:

 self.myStringProperty = [myStringProperty stringByAppendingString:@" more bits"]; 

Follow the memory recommendations for cocoa.

As for dictionaries and other types of collections: refer to what is obtained from the dictionary corresponding to the type you know. If you pull out an object that is actually an NSString, but try to use it as an NSMutableString, your application will crash (with a “selector not found” or similar). Therefore, in this case, you need to create a new NSMutableString from NSString.

Interesting note: Apple decided to make NSMutableString a subclass of NSString. Something about this seems unreasonable to me - if something seems immutable, because it has an NSString type, I want it to be immutable! (But actually it could be NSMutableString.) Compare this to Java, which has a String class and a completely separate BufferedString class.

+5
source

-stringByAppendingString is about to return a new NSString that is different from both of the lines involved. In other words:

 NSString *string3 = [string1 stringByAppendingString:string2]; 

string3 is a brand new line. string1 does not change at all, nothing happens with its memory or contents. The person who told you that maybe he just misunderstood what was happening.

 [mutableString1 appendString:string2]; 

In this case, mutableString1 still points to the same object, but the contents of this object have been modified to include string2.

The last thing to keep in mind is that if you use mutable strings, you should be careful when exchanging links to it. If you pass your mutable string to some function that stores a pointer to that mutable string, and then your code modifies this mutable string at some point in the future, another link points to exactly the same object, which means that the different code will see a change as well. If this is what you want, great, but if not, you have to be careful.

One way to avoid this problem is to declare your @property statements for NSStrings "copy" instead of "save." This will make a copy of your mutable string before setting it in your property, and the -copy method will implicitly provide you with a NON-mutable version, so it will create a copy of the NSString of your NSMutableString.

+3
source

If you follow the rules of memory management, you will be fine using stringByAppendingString. In a nutshell:

  • if you are the owner of the object, you need at some point to release it or auto-advertisement.
  • you have an object if you use the alloc, new or copy method to create it or save it.

Make sure you read Apple’s Memory Management Policies .

In the first code example in your question, you are not using alloc, new, copy, or saving any of the NSStrings involved, so you do not need to do anything to release it. If outside the code that you included in the sample, you use alloc, new, copy or save to any NSStrings, you will need to make sure that they will be released later.

0
source

Source: https://habr.com/ru/post/1342323/


All Articles