简体   繁体   中英

clarification about @property attribute

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!

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.

+[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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM