Nsmutablestring do not use copy

Time:2022-5-10

doubt:

We all knowcopyGenerally used to modifyOn immutable objects with corresponding variable typesFor exampleNSString,NSArrayandNSDictionary。 So why not recommend itcopyTo modifyNSMutableStringandNSMutableArrayBut withstrongAnd?

Test:

I haven’t paid much attention to this problem at ordinary times, so I’ll test it.

1、 First test why nsstring uses copy

First define two string attributes, onestrongOnecopy

Decorate with strong
@property (nonatomic, strong) NSString *str_strong;

Modify with copy
@property (nonatomic, copy) NSString *str_copy;
1. Assignment with variable string nsmutablestring:
- (void)viewDidLoad {
    [super viewDidLoad];
    Nsmutablestring * mutstring = [[nsmutablestring alloc] initwithformat: @ "original variable string"];
    //Assignment
    self.str_strong = mutString;
    self.str_copy = mutString;    
    //Append string
    [mutstring appendstring: @ "+ + + append string];

    NSLog(@"\n mutString: %@, %p, %p \n str_strong: %@, %p, %p \n str_copy: %@, %p, %p \n" , mutString, mutString, &mutString, self.str_strong, _str_strong, &_str_strong, self.str_copy, _str_copy, &_str_copy);
}

The printing results are as follows:

Mutstring: original variable string + + + additional string, 0x28ab6f0, 0x16f027af8 
 str_ Strong: original variable string + + + additional string, 0x28ab6f0, 0x127f0cab0 
 str_ Copy: original variable string, 0x28ab8a0, 0x127f0cab8

It can be seen thatstr_strongandmutStringPointing to object memory is the same becausestrongyesShallow copy(pointer copy), they all point to the same object, the address does not change, and the value is of course the same.
str_copyThe memory address pointing to the object is different from them becausestr_copyObject usedcopy Deep copy, is a new object, which opens up a new memory address instead of the previous address.

2. Assignment with immutable string nsstring:
- (void)viewDidLoad {
    [super viewDidLoad];
    Nsstring * STR = [[nsstring alloc] initwithformat: @ "immutable string"];
    //Assign value
    self.str_strong = str;
    self.str_copy = str;
    NSLog(@"\n str: %@, %p, %p \n str_strong: %@, %p, %p \n str_copy: %@, %p, %p \n" , str, str, &str, self.str_strong, _str_strong, &_str_strong, self.str_copy, _str_copy, &_str_copy);
}

The printing results are as follows:

STR: immutable string, 0x283d55860, 0x16fbcbaf8 
 str_ Strong: immutable string, 0x283d55860, 0x100a15bf0 
 str_ Copy: immutable string, 0x283d55860, 0x100a15bf8

As can be seen from the printing results,str、str_strongandstr_copyThese three points to the same object memory, whether it isstrongstillcopyIt’s all done hereShallow copy, we didn’t reopen a new space, because this timestryesNSString, is immutable.

So generally, we don’t want us to createNSStringString followed by assignmentmutStringChange and change, so they all usecopy。 Of course, if you want the value of the string to followmutStringChanges can also be usedstrong
But if you createNSMutableString, then don’t usecopy

2、 Nsmutablestring do not use copy

We useNSMutableStringYou must want to use the variable attribute of string, but if you usecopyTo modify, then the generated will be immutable. When you call the variable method, the program will crash!
Test:

Modify nsmutablestring with copy
@property (nonatomic, copy) NSMutableString *mutstr_copy;
Nsmutablestring do not use copy

Similarly, don’t be rightNSMutableArrayandNSMutableDictionaryusecopyModification, otherwise there may be a crash.

3、 Summary

  • 1. When the original string isNSString, i.eImmutable stringWhen, whether it’sstrongstillcopyProperty, all of which point to the original object,copyThe operation is only a shallow copy.

  • 2. When the original string isNSMutableStringWhen, i.eVariable stringWhen,strongProperty simply increases the reference count of the original string, andcopyProperty is a deep copy of the original string to produce a new object, andcopyThe property object points to the new object, and thecopyThe type of property object is alwaysNSString, notNSMutableStringTherefore, it is immutable. Calling a variable operation at this time will cause a crash!

  • 3. BecauseNSMutableStringyesNSStringThe parent class pointer can point to the subclass objectcopyThe purpose of is to keep the properties of this object from being affected by the outside world. In this way, no matter whether it is a variable object or an immutable object, what I hold is an immutable copy, which is safer.

So, in the statementNSStringGenerally, we don’t want it to change, so in most cases, we recommend usingcopyTo avoid some unexpected problems caused by the modification of variable strings. And in the statementNSMutableStringYou need to usestrong

infer other things from one fact:

holdNSMutableArrayusecopyDecoration sometimes crashes because the array is added, deleted and modified, andcopyThe array becomes immutableNSArray, there was no response to the addition, deletion and modification method, so it crashed.

  • When modifiedVariable typeProperties of, such asNSMutableArray、NSMutableDictionary、NSMutableString, usestrong
    When modifiedImmutable typeProperties of, such asNSArray、NSDictionary、NSString, usecopy