2

In the following example, does stringWithString:(NSString *) copy the memory address/location of theName to name or it actually copies the data from theName to name?

@interface AddressCard:NSObject
-(void)setName:(NSString *)theName;
@end

@implementation AddressCard
NSString *name;
-(void)setName:(NSString *)theName
{
    if(name!=theName)
    name = [NSString stringWithString:theName];
}
@end

If I change the code to following, what does copy do differently?

@interface AddressCard:NSObject
@property (copy, nonatomic) NSString *name;
@end

@implementation AddressCard
@synthesize name;
@end

In general, does copy (@property attribute) copy the address of the data or copies the data from one variable to another? If it is latter case, are we not consuming a lot of memory when the variable represents large data?

Thank you for your time and response!

Rutvij Kotecha
  • 935
  • 2
  • 10
  • 21
  • 3
    I think you are confused overall as to what `copy` does. All that it does is send a `copy` message to the receiver, which in some cases (immutable `NSStrings` or `NSData`), will just return a retained version of itself, as there is nothing to copy. – Richard J. Ross III Aug 25 '12 at 13:54
  • yes. they very helpful. I apologize for the delay in acknowledging. – Rutvij Kotecha Sep 04 '12 at 16:00

2 Answers2

2

stringWithString will create a copy if it's mutable. But be aware since it's not alloc, init, copy method it's autoreleased. The copy you are now holding will go poof at some point right after that set method exits. If you did initWithString instead, it would create another string as well but retain it.

The copy attribute means the property will be assigned the object returned after sending the copy message to the object that was passed in. That means it's up to that object type to determine how it handles a copy. For your specific string example, (copy) will create a copy of the string back to the caller - a copy that's retained. It's up to the caller to release the retained object. According to the memory guidelines, copy will retain the object.

Community
  • 1
  • 1
bryanmac
  • 38,941
  • 11
  • 91
  • 99
  • Thanks a lot for your response Bryanmac. I think `stringWithString` is a class method and it can initialize and create objects. If you don't mind, can you please rephrase your second part of the response. I am not able to understand it. – Rutvij Kotecha Aug 25 '12 at 13:45
  • Yes, stringWithString is a class method and will create it but see the memory guidelines I added a link to. It will be autoreleased. The copy message will create a retained object. – bryanmac Aug 25 '12 at 13:48
  • 1
    Note that stringWithString will actually only copy the data if the string passed in is mutable. Otherwise, it will return an incremented retainCount version of the input. – Richard J. Ross III Aug 25 '12 at 13:53
  • @everybody: Thank you very much for your response. I apologize for the delay in acknowledging. – Rutvij Kotecha Sep 04 '12 at 16:01
2

+[NSString stringWithString:] will effectively 'copy' the string.

In general, does copy (@property attribute) copy the address of the data or copies the data from one variable to another?

It performs whatever the object considers is a copy. It may return a new object, or it may return itself. For example, +[NSString stringWithString:]could just return the parameter retained and autoreleased if the parameter is already immutable. If the parameter is mutable, then it will return a new instance, so you are guaranteed to have an immutable instance.

If it is latter case, are we not consuming a lot of memory when the variable represents large data?

Aha - but that's the trick! Yes, you could end up making many new allocations with copy, but the trick is often that copies of reference counted objects are truly very shallow in most cases when you favor immutable types and using copy. Many collections types can simply return themselves if they are already immutable, or their ivars may do so, so it's actually a really good idea to ensure you are not passing around mutable objects -- so creating an immutable copy early really allows this optimization to propagate, and saves you a ton of allocations (but not always -- there are a number of corner cases for all these variants).

Note: Not all classes distinguish immutability from mutability, so a copy does not always return an immutable object.

justin
  • 104,054
  • 14
  • 179
  • 226