Hello guys,

Note: This issue has been originally presented in swift-users mailling list 
<https://lists.swift.org/pipermail/swift-users/Week-of-Mon-20170123/004552.html>.
 And then I post it again here at the suggestion 
<https://lists.swift.org/pipermail/swift-users/Week-of-Mon-20170123/004561.html>
 of Jordan Rose:

It might be reasonable to change this behavior, but it probably deserves a bit 
of discussion on swift-evolution; it's not 100%, for-sure a bug.
--- the original content follows this line ---

I encountered a strange behavior when I declared a property with the @NSCopying 
attribute:

// `Person` class inherits from `NSObject` class and conforms to `NSCopying` 
protocol
@NSCopying var employee: Person
and then assigned an external instance of Person class protocol to this 
property within the designated init methods:

// Designated initializer of `Department` class
init( employee externalEmployee: Person ) {
 self.employee = externalEmployee
 super.init()

 // Assertion would fail since Swift do not actually copy the value assigned to 
this property         
 // even though `self.employee` has been marked as `@NSCoyping`
 // assert( self.employee !== externalEmployee )
 }
If I indeed require the deep copying behavior during the init process, instead 
of taking advantage of @NSCopying attribute, I would have to invoke the copy() 
method manually:

init( employee externalEmployee: Person ) {
 // ...
 self.employee = externalEmployee.copy() as! Person  
 // ...
 }
In fact, what really makes me confusing is that @NSCopying semantic does work 
properly within the other parts of the class definition such as normal instance 
methods, or external scope. For instance, if we're assigning an external 
instance of Person to the self.employee proper of Department directly through 
setter rather than initializer:

department.employee = johnAppleseed
then self.employee property and johnAppleseed variable will no longer share the 
same underlying object now. In the other words, @NSCopying attribute makes 
sense.

After I looked through a great deal of results given by Google, and dicussions 
on StackOverflow, I finally end up with nothing helpful — the vast majority of 
articles, documentations as well as issues talking about this similar topics 
only focus on the basic concepts and effects of @NSCopying itself but do not 
mentioned this strange behavior at all — besides one radar descriping the same 
problem (rdar://21383959 <rdar://21383959>) and a final conclusion mentioned in 
a guy's Gist comment: ... values set during initialization are not cloned ...

That is, @NSCopying semantic has no effect in initializers.

Then, what I want to figure out is the reason why @NSCopying semantic will 
become effectless implicitly whithin initializers of a class, and the special 
considerations behind this behavior, if any.

--- END ---

Jordan:

Your observation is correct: @NSCopying currently does not affect initializers. 
This is because accessing a property in an initializer always does direct 
access to the storage rather than going through the setter.
I have tested the identical logic in Objective-C and the NSCopying semantic 
works perfectly within Obj-C's class initializer.

I have no idea whether it's a bug or special consideration. After all, as a 
special consideration, it seems too strange that this behavior has not been 
obviously documented.



Best Regards,
Torin Kwok


Attachment: smime.p7s
Description: S/MIME cryptographic signature

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to