在下面的示例中,stringWithString:(NSString *)
是将theName
的内存地址/位置复制到name
还是实际上复制从 theName
到 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
如果我将代码更改为以下内容,copy
会有何不同?
@interface AddressCard:NSObject
@property (copy, nonatomic) NSString *name;
@end
@implementation AddressCard
@synthesize name;
@end
一般来说,copy
(@property
属性)是复制数据的地址还是将数据从一个变量复制到另一个变量?如果是后一种情况,当变量代表大数据时,我们不是会消耗大量内存吗?
感谢您的宝贵时间和回复!
最佳答案
+[NSString stringWithString:]
将有效地“复制”字符串。
In general, does copy (@property attribute) copy the address of the data or copies the data from one variable to another?
它执行对象认为是复制
的任何操作。它可能返回一个新对象,也可能返回自身。例如,如果参数已经不可变,则 +[NSString stringWithString:] 可以仅返回保留的参数并自动释放。如果参数是可变的,那么它将返回一个新实例,因此保证您拥有一个不可变的实例。
If it is latter case, are we not consuming a lot of memory when the variable represents large data?
啊哈 - 但这就是窍门!是的,您最终可能会使用复制进行许多新的分配,但技巧通常是,当您喜欢不可变类型并使用复制时,在大多数情况下,引用计数对象的副本确实非常浅。许多集合类型可以简单地返回自身(如果它们已经是不可变的),或者它们的 ivars 可能会这样做,因此确保您没有传递可变对象实际上是一个非常好的主意 - 因此尽早创建不可变副本确实允许这种优化传播,并为您节省大量分配(但并非总是如此 - 所有这些变体都有许多极端情况)。
注意:并非所有类都区分不变性和可变性,因此副本并不总是返回不可变对象(immutable对象)。
关于objective-c - 关于@property属性的澄清,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12122409/