简体   繁体   English

如何在 Objective-C 中使用“复制”属性?

[英]How to use “copy” property in Objective-C?

I have read through many materials online which all explain when people should use " copy " instead of " strong ".我在网上阅读了很多资料,这些资料都解释了人们何时应该使用“ copy ”而不是“ strong ”。

"The copy attribute is an alternative to strong. Instead of taking ownership of the existing object, it creates a copy of whatever you assign to the property, then takes ownership of that. Only objects that conform to the NSCopying protocol can use this attribute..." “copy 属性是 strong 的替代品。它不是获取现有对象的所有权,而是创建您分配给该属性的任何内容的副本,然后获得所有权。只有符合NSCopying协议的NSCopying才能使用此属性。 ..”

And there are plenty of example codes showing when using "copy", the original value stays the same.并且有大量示例代码显示使用“复制”时,原始值保持不变。

However, I'm new to Objective-C .但是,我是Objective-C新手。 I really want to know how to use the newly assigned value.我真的很想知道如何使用新分配的值。 Where is the "new instance(copy)" with the "new value"?带有“新值”的“新实例(副本)”在哪里? Do I need any additional methods to change the original value if I want to?如果我愿意,是否需要任何其他方法来更改原始值?

It will be great if someone can share an example for this part not the one proving the original value is not changed, which is everywhere.如果有人可以分享这部分的示例,而不是证明原始值没有改变的示例,那就太好了,这无处不在。

What the copy attribute does behind the scenes is to create a setter like this: copy属性在幕后所做的是创建一个像这样的 setter:

- (void)setMyCopiedProperty:(MyClass *)newValue {
    _myCopiedProperty = [newValue copy];
}

this means that whenever someone does something like this object.myCopiedProperty = someOtherValue;这意味着每当有人做这样的事情时object.myCopiedProperty = someOtherValue; , the someOtherValue is sent a copy message telling it to duplicate itself. , someOtherValue被发送一个copy消息,告诉它复制自己。 The receiver gets then a new pointer (assuming copy is correctly implemented), to which no-one excepting the receiver object has access to.接收者然后获得一个新的指针(假设正确实现了copy ),除了接收者对象之外没有人可以访问该指针。

You can look at copy as being exclusive in some kind of way:您可以以某种方式copy视为排他性:

  • the clients that set the property don't have access to the actual set value设置属性的客户端无权访问实际设置值
  • the receiver doesn't have access to the original passed value.接收者无权访问原始传递的值。

Beware of the caveats, though:但请注意以下警告:

  • a copied NSArray doesn't copy its objects, so you might end up thinking that a @property(copy) NSArray<MyClass *> *myProperty is safe, however while the array itself is safe from being modified, the objects held by the array share the same reference.复制的NSArray不会复制其对象,因此您最终可能会认为@property(copy) NSArray<MyClass *> *myProperty是安全的,但是虽然数组本身不会被修改,但数组持有的对象共享相同的参考。 Same is true for any collection class ( NSDictionary , NSSet , etc)对于任何集合类( NSDictionaryNSSet等)也是如此
  • if the property matches to a custom class you need to make sure the copy method does its job - ie creating a new object.如果该属性与自定义类匹配,您需要确保copy方法完成其工作 - 即创建一个新对象。 This happens for all Cocoa/CocoaTouch classes that conform to NSCopying , however for other classes this might or not be true, depending on implementation (myself I didn't saw yet a class that lies about its copy method, however you never know)发生这种情况的符合所有的Cocoa / CocoaTouch类NSCopying ,但是对于其他类,不过这是否不是真实的,这取决于执行(我自己,我也没锯但一类谎言的copy方法,但是你永远不知道)

Try this:试试这个:

Model.h模型.h

@interface Model: NSObject

@property (nonatomic,strong)NSString *firstName;

@property (nonatomic,copy) NSString *lastName;

@end

ViewController.m视图控制器.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"

An instance of a class is a discrete copy.类的实例是离散副本。 When you assign an instance of a class to be the value of a property with the copy attribute, a clone of that instance is made and that clone becomes the value of the property.当您将类的实例分配为具有copy属性的属性值时,会创建该实例的克隆,并且该克隆成为该属性的值。 There is no relationship between the original and its clone, so the property does not have access to the original instance at all.原始实例与其克隆之间没有任何关系,因此该属性根本无法访问原始实例。 Changing an attribute of the property's value is changing the clone.更改属性值的属性就是更改克隆。

Note:注意:

If you implement the setter for a copy property, it is your responsibility to ensure it actually creates a copy.如果您为copy属性实现 setter,则您有责任确保它实际上创建了一个副本。 As is true with all the attributes for a property, they only have meaning when the compiler is generating (synthesizing) the setter and/or getter for you.与属性的所有属性一样,它们仅在编译器为您生成(合成)setter 和/或 getter 时才有意义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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