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

Does your toilet smell like rotten eggs? Be careful!

If you smell a pungent smell of rotten eggs in th...

Was Musk's Starship's first flight a success or a failure?

Recently, SpaceX conducted another launch test. O...

20 thoughts on marketing, copywriting, and new media!

1. There is a very famous marginal effect in econ...

Hong Kong version iPhone 6 briefly activated in Zhongguancun store

Faced with the rise of e-commerce companies such ...

A review of the design process of the homepage of vivo's official website APP

What is the vivo official website APP? The vivo o...

How do e-commerce and education industry communities attract new members?

Today I would like to share with you some of my t...

A shot in the arm for your code — dependency injection

[[151314]] What is Dependency Injection? Dependen...

I didn’t spend a penny on promotion and achieved 23 million app downloads!

The author of this article spent 6 hours to creat...