When should I use copy and when should I use strong for NSString attributes?

When should I use copy and when should I use strong for NSString attributes?

When should I use copy and when should I use strong for NSString attributes?

When we declare an NSString property, we usually have two choices for its memory-related characteristics (based on the ARC environment): strong and copy. So what is the difference between the two? When should we use strong and when should we use copy? Let's take a look at an example.

Example

We define a class and declare two string properties for it as follows:

  1. @interface TestStringClass ()
  2.  
  3. @property (nonatomic, strong) NSString *strongString;
  4. @property (nonatomic, copy) NSString *copyedString;
  5.  
  6. @end

The above code declares two string properties, one with a strong memory attribute and the other with a copy memory attribute. Let's take a look at the difference between them.

First, we use an immutable string to assign values ​​to these two properties.

  1. - ( void )test {
  2.  
  3. NSString *string = [NSString stringWithFormat:@ "abc" ];
  4. self.strongString = string;
  5. self.copyedString = string;
  6.  
  7. NSLog(@ "origin string: %p, %p" , string, &string);
  8. NSLog(@ "strong string: %p, %p" , _strongString, &_strongString);
  9. NSLog(@ "copy string: %p, %p" , _copyedString, &_copyedString);
  10. }

The output is:

  1. origin string: 0x7fe441592e20 , 0x7fff57519a48  
  2. strong string: 0x7fe441592e20 , 0x7fe44159e1f8  
  3. copy string: 0x7fe441592e20 , 0x7fe44159e200  

We can see that in this case, no matter the object has the strong or copy attribute, the address it points to is the same, that is, the address pointed to by string. If we switch to the MRC environment and print the reference count of string, we will see that its reference count value is 3, that is, both the strong operation and the copy operation increase the reference count value of the original string object by 1.

Next, let's change string from an immutable object to a mutable object and see what the result will be.

  1. NSString *string = [NSString stringWithFormat:@ "abc" ];

To:

  1. NSMutableString *string = [NSMutableString stringWithFormat:@ "abc" ];

The output is:

  1. origin string: 0x7ff5f2e33c90 , 0x7fff59937a48  
  2. strong string: 0x7ff5f2e33c90 , 0x7ff5f2e2aec8  
  3. copy string: 0x7ff5f2e2aee0 , 0x7ff5f2e2aed0  

It can be found that the copy attribute string no longer points to the string object, but a deep copy of the string string is made, and the _copyedString object is made to point to the string. In the MRC environment, printing the reference counts of the two objects shows that the reference count of the string object is 2, while the reference count of the _copyedString object is 1.

At this point, if we modify the string string, we can see that: because _strongString and string point to the same object, the value of _strongString will also change (it should be noted that the type of _strongString is actually NSMutableString, not NSString); and _copyedString points to another object, so it will not change.

in conclusion

Since NSMutableString is a subclass of NSString, an NSString pointer can point to an NSMutableString object, so it is OK for our strongString pointer to point to a mutable string.

As can be seen from the above example, when the source string is NSString, since the string is immutable, no matter whether it is an object with strong or copy attributes, it points to the source object, and the copy operation only makes a shallow copy.

When the source string is NSMutableString, the strong attribute only increases the reference count of the source string, while the copy attribute makes a deep copy of the source string, generating a new object, and the copy attribute object points to this new object. It should also be noted that the type of this copy attribute object is always NSString, not NSMutableString, so it is immutable.

There is also a performance issue here, that is, when the source string is NSMutableString, strong simply increases the reference count of the object, while the copy operation performs a deep copy, so the performance will be different. If the source string is NSString, there is no such problem.

Therefore, when declaring NSString properties, whether to choose strong or copy can be determined according to the actual situation. However, generally when we declare an object as NSString, we don't want it to change, so in most cases, we recommend using copy to avoid some unexpected problems caused by the modification of mutable strings.

There are some interesting things about string memory management, which you can learn by referring to NSString feature analysis.

refer to

NSString copy not copying?

NSString feature analysis and learning

When to use copy and when to use strong in NSString

<<:  iOS uses Charles (Blue and White Porcelain) to capture packets and tamper with returned data

>>:  IBOutletCollection

Recommend

Google will charge Android phone makers up to $40 per device

[[246856]] *** News: According to documents obtai...

Why don’t TVs nowadays have power buttons and can’t be turned off?

Smart TVs have made our entertainment life more c...

“I’m autistic again”… What are real autistic people like?

In recent years, young people like to use joking ...

2019 Kuaishou and Douyin User Research Report!

The following is the full report: (Reply "DK...

World AIDS Day丨How does AIDS destroy our bodies step by step?

Today is December 1st, the first day of December ...

Apple in the post-Steve Jobs era: More users but fewer fans

[[127006]] Emotional communication between brands...