[英]How to use “copy” property in Objective-C?
我在网上阅读了很多资料,这些资料都解释了人们何时应该使用“ copy
”而不是“ strong
”。
“copy 属性是 strong 的替代品。它不是获取现有对象的所有权,而是创建您分配给该属性的任何内容的副本,然后获得所有权。只有符合NSCopying
协议的NSCopying
才能使用此属性。 ..”
并且有大量示例代码显示使用“复制”时,原始值保持不变。
但是,我是Objective-C
新手。 我真的很想知道如何使用新分配的值。 带有“新值”的“新实例(副本)”在哪里? 如果我愿意,是否需要任何其他方法来更改原始值?
如果有人可以分享这部分的示例,而不是证明原始值没有改变的示例,那就太好了,这无处不在。
copy
属性在幕后所做的是创建一个像这样的 setter:
- (void)setMyCopiedProperty:(MyClass *)newValue {
_myCopiedProperty = [newValue copy];
}
这意味着每当有人做这样的事情时object.myCopiedProperty = someOtherValue;
, someOtherValue
被发送一个copy
消息,告诉它复制自己。 接收者然后获得一个新的指针(假设正确实现了copy
),除了接收者对象之外没有人可以访问该指针。
您可以以某种方式copy
视为排他性:
但请注意以下警告:
NSArray
不会复制其对象,因此您最终可能会认为@property(copy) NSArray<MyClass *> *myProperty
是安全的,但是虽然数组本身不会被修改,但数组持有的对象共享相同的参考。 对于任何集合类( NSDictionary
、 NSSet
等)也是如此copy
方法完成其工作 - 即创建一个新对象。 发生这种情况的符合所有的Cocoa / CocoaTouch类NSCopying
,但是对于其他类,不过这是否不是真实的,这取决于执行(我自己,我也没锯但一类谎言的copy
方法,但是你永远不知道)试试这个:
模型.h
@interface Model: NSObject
@property (nonatomic,strong)NSString *firstName;
@property (nonatomic,copy) NSString *lastName;
@end
视图控制器.m
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
Model *model = [[Model alloc]init];
NSMutableString *str = [[NSMutableString alloc]initWithString:@"test"];
model.firstName = str;
model.lastName = str;
NSLog(@"%@, %@", model.firstName, model.lastName);
[str appendString:@"string"];
NSLog(@"%@, %@ ", model.firstName, model.lastName);}
Output :
1st Nslog = "test", "test"
2nd Nslog = "teststring", "test"
类的实例是离散副本。 当您将类的实例分配为具有copy
属性的属性值时,会创建该实例的克隆,并且该克隆成为该属性的值。 原始实例与其克隆之间没有任何关系,因此该属性根本无法访问原始实例。 更改属性值的属性就是更改克隆。
注意:
如果您为copy
属性实现 setter,则您有责任确保它实际上创建了一个副本。 与属性的所有属性一样,它们仅在编译器为您生成(合成)setter 和/或 getter 时才有意义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.