@NSCopying does not appear to copy
| Originator: | jose.ibanez | ||
| Number: | rdar://21383959 | Date Originated: | June 15, 2015 |
| Status: | Open | Resolved: | |
| Product: | Swift | Product Version: | 1.2, 2 |
| Classification: | Serious Bug | Reproducible: | Always |
gist: https://gist.github.com/jose-ibanez/c813f10d301c0e2b54be
Summary:
Swift properties declared with the `@NSCopying` attribute do not actually copy the value assigned to them or read from them.
Steps to Reproduce:
1. Declare a property with the `@NSCopying` attribute with a type that conforms to the `NSCopying` protocol:
class Foo : NSObject, NSCopying { .. }
class Test : NSObject {
@NSCopying public var foo : Foo
}
2. Set the property:
let test = Test()
let foo = Foo()
foo.bar = "initial"
test.foo = foo
3. Observe that `foo` and `test.foo` are different pointers.
foo === test.foo // expected: false, actual: true
3. Change a property on foo:
foo.bar = "changed"
4. Observe the property on Test has changed:
print(test.foo.bar) // expected: "initial", actual: "changed"
Expected Results:
Objects assigned to or read from a property with the `@NSCopying` attribute should create a copy of the object using `copyWithZone()`
Actual Results:
The `@NSCopying` attribute appears to do nothing.
Version:
Xcode 6.3.2 / Swift 1.2
Xcode 7b1 / Swift 2
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!
Added clarifying comment.
I've learned something with the help of the swift-lang slack org that clarifies the issue a bit, but I believe there is still a bug here.
So, the beginning of my problem was that when you assign to a property before calling
super.init()it doesn't use the property, so no copying takes place, as in the following example:Rather, foo is copied only when it's set using the property after initialization, so this works:
However, the property foo does not return a copy when it is read, so it can still be mutated without being set:
I can live with having to manually copy during init, but I believe that @NSCopying properties should also return a copy of the object.