8

I read somewhere that with NSString in an object, one has to use copy instead of retain. Can someone explain if this is correct and why?

For example I have the following declaration for my singleton:

#import <foundation/Foundation.h>
@class FaxRecipient;

@interface MyManager : NSObject {
    NSString *subject;
    NSString *reference;
    NSString *coverSheet;
    FaxRecipient *faxRecipient;

}

@property (nonatomic, retain) NSString *test1;
@property (nonatomic, retain) NSString *test2;
@property (nonatomic, retain) NSString *test3;
@property (nonatomic,retain) FaxRecipient *faxRecipient;



+ (id)sharedManager;

@end
milof
  • 696
  • 9
  • 25
  • 1
    The code that you mentioned is correct. You have to use retain. – Satyam May 31 '11 at 05:41
  • It's my understanding to use retain as well. I'd be interested to here of alternative theories and the reasons for them. One reason that does spring to mind is that copying means that if you get passed a NSMutableString instead of a NSString then your class is not effected if the mutable string is changed by another class. NSString would be different because it's fixed. – drekka May 31 '11 at 05:52
  • 1
    possible duplicate of http://stackoverflow.com/questions/387959/nsstring-property-copy-or-retain – Jason May 31 '11 at 05:57
  • @Derek Clarkson, that's exactly the reason that you should use 'copy' in this case. If someone sets the test1 property to a NSString*, the copy is implemented as a retain anyway, so no difference. If they pass in a NSMutableString*, though, an immutable copy is made and the property points to that, so no surprises. – Caleb May 31 '11 at 06:08
  • @Caleb - True, I wasn't referring to the sample code. Just giving my general understanding :) – drekka May 31 '11 at 06:11

5 Answers5

8

I think "has to" in the sense of must is a little strong. You can use either copy or retain, but you should generally use copy for your NSString* properties because:

  1. You usually don't want a string property to change under your nose;
  2. NSMutableString is a subclass of NSString, so it's entirely possible that someone might set your NSString* property to point to a mutable string, thus creating the potential for the string to be changed while you're using it;
  3. For immutable classes like NSString, copy operations end up just retaining the original object anyway.

Considering those three points, it's hard to think of a good reason to use retain instead of copy for your NSString properties.

Kjuly
  • 34,476
  • 22
  • 104
  • 118
Caleb
  • 124,013
  • 19
  • 183
  • 272
4

prefer copy. it does not matter whether your class is or is not a singleton.

i wrote a fairly lengthy explanation for this, which details mutable and immutable types here: NSMutableString as retain/copy

Community
  • 1
  • 1
justin
  • 104,054
  • 14
  • 179
  • 226
3

You can also use copy instead of retain. I use copy for NSString. There is good discussion on this topic. Here is a stackoverflow post NSString Copy or Retain?

Community
  • 1
  • 1
Rahul Vyas
  • 28,260
  • 49
  • 182
  • 256
0

You could use either,In both cases you will be owner of the objects and need to be released in dealloc.

Difference between copy and retain .

retain :--> It just increase the retain count on the exist object.

copy :--> it crate the new object for your property

In both cases: you will have the ownership of objects.

Read Apple memory management concept.

@ Claus Broch: From Apple Documentation

You take ownership of an object if you create it using a method whose name begins with “alloc”, “new”, “copy”, or “mutableCopy” (for example, alloc, newObject, or mutableCopy), or if you send it a retain message.

Jhaliya - Praveen Sharma
  • 31,697
  • 9
  • 72
  • 76
  • @Jhaliya Just because you retain an object doesn't mean you become the owner. As @Caleb points out there is no way you are protected against somebody sendin you a NSMutableString and changing that later on. – Claus Broch May 31 '11 at 07:05
  • @Claus Broch : So tell ... why do we use retain ? – Jhaliya - Praveen Sharma May 31 '11 at 07:13
  • @Jhaliya To get our own reference to an object thus ensuring it doesn't get deallocated when everybody else looses interest in it – Claus Broch May 31 '11 at 07:39
  • @Claus Broch : Good definition , my other question , Do you own it release ? – Jhaliya - Praveen Sharma May 31 '11 at 07:43
  • @Jhaliya I would bend that definition by Apple to say "responsibility" or "shared ownership" instead of "ownership". You do not get an exclusive ownership over an object by retaining it. The original question from @milofaris specifically asked about NSString and as @Caleb pointed out you do not have fully exclusive ownership over that object by using retain. – Claus Broch May 31 '11 at 07:54
  • @Claus Broch : no offense but would advice you to read apple documentation and correct yourself whether they say "responsibility" , "shared ownership" OR "ownership" which i used in my answer. – Jhaliya - Praveen Sharma May 31 '11 at 07:58
  • 1
    @Jhaliya: No offense either. No point in starting a war on words. In regards to that part of the Apple docs you're perfectly right in your use of the terms. But there is more to it than that - which was what I was trying to explain. – Claus Broch May 31 '11 at 08:19
  • @Claus Broch : you are absolutely with your words,thanks for healthy conversion.. – Jhaliya - Praveen Sharma May 31 '11 at 08:42
-2

You should use the retain value in this instance. The reason for this is that 1. you don't want the object to be deallocated 2. you are most likely going to want to change the value of the NSString at some point

Using the copy attribute is basically saying that the value of your NSString should not change without warning. i.e. it will stop the value of the NSString being set and retrieved at the same time.

For this implementation, you should use retain, or at least thats my understanding. For more look here: http://cocoawithlove.com/2010/06/assign-retain-copy-pitfalls-in-obj-c.html

Chance Hudson
  • 2,849
  • 1
  • 19
  • 22