Short answer: if you’re using an NSString you should be using copy.
Copy makes a copy of a variable.
Retain shifts the pointer when set to a new variable. i.e. it becomes the new variable.
Here’s an example that clarifies whether to use retain or copy:
NSMutableString *someName = [NSMutableString stringWithString:@”Dougal”];
Person *p = [[[Person alloc] init] autorelease];
p.name = someName;
If p is declared using copy then it’s set to Dougal on line 3 and, on completion, still has that value.
However, if p is declared using retain then it’s set to someName. So, when someName is set to “Zebedee”, p is also set to “Zebedee”.
More on this here: http://stackoverflow.com/questions/387959/nsstring-property-copy-or-retain
And if you want to get into the details of implementing NSCopying or NSCopyObject then you should look at Rob Napier’s post: http://robnapier.net/blog/implementing-nscopying-439