A few concepts about copy

1. Copy

  • That is to copy, to make copies, so that the original object and the copy are independent of each other

2. Immutable copy

That is, the copy method, regardless of whether the original object is mutable, produces an immutable copy

3. MutableCopy

The mutableCopy method produces mutable copies regardless of whether the original object is mutable

For example

NSString *str = @"hello world"; [str copy]; // copy hello World NSString [STR mutableCopy]; // Copy a string of type NSMuttableString with hello WorldCopy the code

4. A deep copy

Copy content, create new objects

  • The address of the copied object is different from that of the original object. Changing the value of the copied object has no impact on the original object
  • Deep copy is copying the entire object into another block of memory

5. Shallow copy

Pointer copy, no new object generated

  • The address of the copied object is the same as that of the original object. Modifying the value of the copied object will affect the original object
  • Shallow copy is reference count +1 based on the original object

Pay attention to the point

Copy and deep copy are two different concepts.

  • When the original object is immutable,copyThe method is shallow copy
  • When the original object is mutable,copyThe solution is deep copy
  • mutableCopyMethods are deep copies regardless of whether the original object is mutable or immutable

security

1. You don’t want objects to be modified unintentionally

For example

@property(nonatomic,strong)NSString *str; NSMutableString *mutableStr = [NSMutableString stringWithFormat:@"123"]; self.str = mutableStr; NSLog(@"%@----%p", self.str,self.str); NSLog(@"%@----%p", mutableStr,mutableStr); [mutableStr appendString:@"456"]; / / modify mutableStr NSLog (@ "% @, % p", the self. The STR, the self. The STR); NSLog(@"%@----%p", mutableStr,mutableStr); 2021-04-04 11:34:23.227973+0800 Copy Example [2344:73458] 123---- 0x6000035C35A0 2021-04-04 11:34:23.228096+0800 Copy Example [2344:73458] 123---- 0x6000035C35A0 2021-04-04 11:34:23.228187+0800 Copy Example [2344:73458] 123456---- 0x6000035C35A0 2021-04-04 11:34:23.228268+0800 Copy Example [2344:73458] 123456---- 0x6000035C35A0Copy the code

As you can see, when you modify a mutableStr, it causes the STR to change, which is obviously not desirable. If we want to change a mutableStr without affecting the STR, then we should use the copy modifier

@property(nonatomic,copy)NSString * STR; , the rest remains the same, and the result is as follows

2021-04-04 11:38:04.092095+0800 Copy Example [2388:76204] 123---- 0xC65D21ED94e36C08 2021-04-04 11:38:04.092227+0800 Copy Example [2388:76204] 123---- 0x600000943ED0 2021-04-04 11:38:04.092324+0800 Copy Example [2388:76204] 123---- 0xC65D21ED94e36C08 2021-04-04 11:38:04.092471+0800 Copy Example [2388:76204] 123456---- 0x600000943ED0Copy the code

When a property is decorated with strong, a mutable string is assigned to the property, which points to the same object as the mutable string. When the mutable string is modified, the property is also modified. To prevent the property from being inadvertently modified elsewhere, we use the copy modifier

2. The mutable and immutable properties of the object change, resulting in an error in the usage method

For example

@property(nonatomic,copy)NSMutableString *mutableString; NSMutableString * STR = [NSMutableString stringWithFormat:@"1234"]; Self. mutableString = STR; // assign STR to mutableString NSLog(@"string:%@ -- mutableString:%@", STR,self.mutableString); [self.mutableString appendString:@"5678"]; NSLog(@"string:%@ --- mutableString:%@",str,self.mutableString); The output is string:1234 -- mutableString:1234 unrecognized selector sent to instanceCopy the code

The key thing that’s wrong here is self.mutableString = STR; And [self mutableString appendString: @ “5678”);

  • self.mutableString = str;

This line of code is essentially [self.mutableString setMutableString: STR]; , the concrete implementation is as follows

-(void)setMutableString:(NSMutableString *)mutableString{
    if (_mutableString != mutableString) {
        [_mutableString release];
        _mutableString = [mutableString copy];
    }
}
Copy the code

Main code _mutableString = [mutableString copy];

  • One of themutableStringIs the parameter passed instr
  • usecopyMethod because attributes are defined bycopymodified
  • becausestrIs itself a mutable string, therefore a mutable stringcopyThe resulting value is an immutable object, i.e[mutableString copy]You get immutable objects
  • mutableStringAlthough originally defined as a mutable string, immutable objects are assigned to_mutableString, so it’s still an immutable string

[self.mutableString appendString:@”5678″];

  • Immutable objects are notappendStringMethod, so the errorunrecognized selector sent to instance

A mutable string copy is an immutable string, even if it’s assigned to a mutable property, which is immutable, but we thought it was mutable, so we might use the wrong method


Refer to the blog

IOS Basics (1) Copy