Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSString property: copy or retain?

Let's say I have a class called SomeClass with a string property name:

@interface SomeClass : NSObject {     NSString* name; }  @property (nonatomic, retain) NSString* name;  @end 

I understand that name may be assigned a NSMutableString in which case this may lead to errant behavior.

  • For strings in general, is it always a good idea to use the copy attribute instead of retain?
  • Is a "copied" property in any way less efficient than such a "retain-ed" property?
like image 856
Debajit Avatar asked Dec 23 '08 01:12

Debajit


People also ask

Do I need to release NSString?

If you create an object using a method that begins with init, new, copy, or mutableCopy, then you own that object and are responsible for releasing it (or autoreleasing it) when you're done with it. If you create an object using any other method, that object is autoreleased, and you don't need to release it.

Why copy NSString?

So NSString 's copy simply calls retain . NSMutableString 's copy makes an actual copy. It is usually better to give spit out an NSString * because people won't have to copy it all the time.

What does NSString mean?

A static, plain-text Unicode string object that bridges to String ; use NSString when you need reference semantics or other Foundation-specific behavior. iOS 2.0+ iPadOS 2.0+ macOS 10.0+ Mac Catalyst 13.0+ tvOS 9.0+ watchOS 2.0+


2 Answers

For attributes whose type is an immutable value class that conforms to the NSCopying protocol, you almost always should specify copy in your @property declaration. Specifying retain is something you almost never want in such a situation.

Here's why you want to do that:

NSMutableString *someName = [NSMutableString stringWithString:@"Chris"];  Person *p = [[[Person alloc] init] autorelease]; p.name = someName;  [someName setString:@"Debajit"]; 

The current value of the Person.name property will be different depending on whether the property is declared retain or copy — it will be @"Debajit" if the property is marked retain, but @"Chris" if the property is marked copy.

Since in almost all cases you want to prevent mutating an object's attributes behind its back, you should mark the properties representing them copy. (And if you write the setter yourself instead of using @synthesize you should remember to actually use copy instead of retain in it.)

like image 184
Chris Hanson Avatar answered Sep 24 '22 04:09

Chris Hanson


Copy should be used for NSString. If it's Mutable, then it gets copied. If it's not, then it just gets retained. Exactly the semantics that you want in an app (let the type do what's best).

like image 23
Frank Krueger Avatar answered Sep 26 '22 04:09

Frank Krueger