when we declare a NSString property, there are usually two choices (based on the ARC environment) for its memory-related attributes: Strong and copy. So what's the difference between the two? When should I use strong, when should I use copy? Let's look at an example first.
Example
We define a class and declare two string attributes for it, as follows:
1 2 3 4 |
@interface TestStringClass () @property (nonatomic, strong) NSString *strongString; @property (nonatomic, copy) NSString *copyedString; @end |
The above code declares two string properties, one of which is strong, and the other is copy. Let's take a look at their differences.
First, we use an immutable string to assign values to these two properties,
1 2 3 4 5 6 7 8 |
- (void)test { NSString *string = [NSString stringWithFormat:@ "abc" ]; self.strongString = string; self.copyedString = string; NSLog(@ "origin string: %p, %p" , string, &string); NSLog(@ "strong string: %p, %p" , _strongString, &_strongString); NSLog(@ "copy string: %p, %p" , _copyedString, &_copyedString); } |
The output is:
1 2 3 |
origin string: 0x7fe441592e20, 0x7fff57519a48 strong string: 0x7fe441592e20, 0x7fe44159e1f8 copy string: 0x7fe441592e20, 0x7fe44159e200 |
We want to see, in this case, whether the object is a strong or a copy property, the address it points to is the same, that is, the address that the string points to. If we switch to the MRC environment and print the reference count of the string, we will see that its reference value is 3, that is, both the strong operation and the copy operation add 1 to the reference count value of the original string object.
Next, we'll change the string from immutable to mutable to see what the result will be. The following sentence will be
1 |
NSString *string = [NSString stringWithFormat:@ "abc" ]; |
Change to:
1 |
NSMutableString *string = [NSMutableString stringWithFormat:@ "abc" ]; |
The output is:
1 2 3 |
origin string: 0x7ff5f2e33c90, 0x7fff59937a48 strong string: 0x7ff5f2e33c90, 0x7ff5f2e2aec8 copy string: 0x7ff5f2e2aee0, 0x7ff5f2e2aed0 |
As you can see, the Copy property string no longer points to a string string object, but rather a deep copy of the string, and the _copyedstring object points to the string. In the MRC environment, you can see that the reference count for the string object is 2, and the reference count for the _copyedstring object is 1.
At this point, if we go to modify string string, we can see: Because _strongstring and string are pointing to the same object, so the value of _strongstring will follow the change (note that at this time _ The type of strongstring is actually nsmutablestring, not nsstring), and _copyedstring is pointing to another object, so it does not change.
Conclusion
Since Nsmutablestring is a subclass of NSString, a nsstring pointer can point to the Nsmutablestring object and let our strongstring pointer point to a mutable string that is OK. As the above example shows, when the source string is NSString, because the string is immutable, the object, whether it is a strong or copy property, is pointing to the source object, and the copy operation only makes a shallow copy. When the source string is nsmutablestring, the strong property simply increases the reference count of the source string, while the copy property makes a secondary deep copy of the source string, producing a new object, and the Copy Property object points to the new object. It is also important to note that the type of the Copy Property object is always NSString, not nsmutablestring, so it is immutable.
There is also a performance problem where the source string is Nsmutablestring,strong is simply an increase in the reference count of the object, while the copy operation performs a deep copy, so the performance will vary. If the source string is nsstring, then there is no problem.
Therefore, in the declaration of the NSString property, whether the choice of strong or copy, can be determined according to the actual situation. However, in general, when we declare an object as NSString, we do not want it to change, so in most cases we recommend using copy to avoid some unintended problems caused by the modification of mutable strings.
NSString property when to use copy, when to use strong?