Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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".

"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..."

And there are plenty of example codes showing when using "copy", the original value stays the same.

However, I'm new to 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.

like image 208
user2457766 Avatar asked Sep 21 '16 03:09

user2457766


People also ask

What does copy do in Objective C?

Copy is useful when you do not want the value that you receive to get changed without you knowing. For example if you have a property that is an NSString and you rely on that string not changing once it is set then you need to use copy.

What is copy property?

"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..."

What is assign property in Objective C?

assign -assign is the default and simply performs a variable assignment -assign is a property attribute that tells the compiler how to synthesize the property's setter implementation -I would use assign for C primitive properties and weak for weak references to Objective-C objects.


1 Answers

What the copy attribute does behind the scenes is to create a setter like this:

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

this means that whenever someone does something like this object.myCopiedProperty = someOtherValue;, the someOtherValue is sent a copy message telling it to duplicate itself. The receiver gets then a new pointer (assuming copy is correctly implemented), to which no-one excepting the receiver object has access to.

You can look at copy as being exclusive in some kind of way:

  • 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. Same is true for any collection class (NSDictionary, NSSet, etc)
  • if the property matches to a custom class you need to make sure the copy method does its job - i.e. creating a new object. 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)
like image 144
Cristik Avatar answered Oct 11 '22 13:10

Cristik