protocol Copyable { func copy() -> Self
} final class Storage:Copyable { var keys: [String] = [] var values: [Int] = [] func copy() -> Storage { let s = Storage() s.keys = keys s.values = values return s } } public struct Document:Copyable { var _storageReference: Storage public init() { self._storageReference = Storage() } public init(_ values: DocumentValues) { self._storageReference = values._storageReference } public var values: DocumentValues { get { return DocumentValues(self) } set { self = Document(newValue) } } public func copy() -> Document { var d = Document() d._storageReference = _storageReference.copy() return d } } var document = Document() let copy = document.copy() // just assume we already added some values and can mutate safely on a given index // mutation in place document.values[0] = 10 // <--- this will only mutate `document` but not `copy` You use `class` property inside `struct`, so the `struct` is no longer copyable. You have to do it yourself. Zhaoxin On Fri, Nov 18, 2016 at 10:09 PM, Adrian Zubarev < adrian.zuba...@devandartist.com> wrote: > Ups sorry for CCing the post to the evolution list. That happens from time > to time. :/ > > > > -- > Adrian Zubarev > Sent with Airmail > > Am 18. November 2016 um 15:07:43, Adrian Zubarev ( > adrian.zuba...@devandartist.com) schrieb: > > I apologize about the weak/unowned issue I mentioned. I kinda missed that > portion from the docs Weak references do not affect the result of this > function.. > > Okay it’s clear to me now why the result is evaluated as false. > > But how do I solve the COW problem for mutable views? > > > -- > Adrian Zubarev > Sent with Airmail > > Am 18. November 2016 um 15:04:55, Adrian Zubarev ( > adrian.zuba...@devandartist.com) schrieb: > > This doesn’t make any sense. > > Somewhere from the Swift book: > > Weak and unowned references enable one instance in a reference cycle to > refer to the other instance *without keeping a strong hold on it*. The > instances can then refer to each other without creating a strong reference > cycle. > > From the sdlib of the function isKnownUniquelyReferenced: > > Returns a Boolean value indicating whether the given object is a class > instance known to have *a single strong reference*. > > unowned doesn’t increase the reference count, so the view in the examples > I showed should have no strong reference to that class instance. The only > strong reference that exists is from Document. So why exactly is the > result of the second isKnownUniquelyReferenced call false again? > > > -- > Adrian Zubarev > Sent with Airmail > > Am 18. November 2016 um 14:50:57, Zhao Xin (owe...@gmail.com) schrieb: > > >Why is the second check false, even if the property is marked as unowned for > the view? > > Please search the mailing list, this is not the first time it comes as a > new question. Shortly speaking, it is `false` only because you used > `unowned`. If you you can grantee it always exists. Just use it directly, > this is what `unowned` for. If you can't grantee that. You should use > `weak` and check it with `if let` or `if foo == nil` > > Zhaoxin > > > On Fri, Nov 18, 2016 at 8:05 PM, Adrian Zubarev via swift-users < > swift-users@swift.org> wrote: > >> Hi there, >> >> I just can’t get my head around mutable views and COW. >> >> Here is a small example: >> >> final class Storage { >> >> var keys: [String] = [] >> var values: [Int] = [] >> } >> >> public struct Document { >> >> var _storageReference: Storage >> >> public init() { >> >> self._storageReference = Storage() >> } >> >> public init(_ values: DocumentValues) { >> >> self._storageReference = values._storageReference >> } >> >> public var values: DocumentValues { >> >> get { return DocumentValues(self) } >> >> set { self = Document(newValue) } >> } >> } >> >> public struct DocumentValues : MutableCollection { >> >> unowned var _storageReference: Storage >> >> init(_ document: Document) { >> >> self._storageReference = document._storageReference >> } >> >> public var startIndex: Int { >> >> return self._storageReference.keys.startIndex >> } >> >> public var endIndex: Int { >> >> return self._storageReference.keys.endIndex >> } >> >> public func index(after i: Int) -> Int { >> >> return self._storageReference.keys.index(after: i) >> } >> >> public subscript(position: Int) -> Int { >> >> get { return _storageReference.values[position] } >> >> set { self._storageReference.values[position] = newValue } // That >> will break COW >> } >> } >> >> First of all the _storageReference property is unowned because I wanted >> to check the following: >> >> var document = Document() >> >> print(CFGetRetainCount(document._storageReference)) //=> 2 >> print(isKnownUniquelyReferenced(&document._storageReference)) // true >> >> var values = document.values >> >> print(CFGetRetainCount(values._storageReference)) //=> 2 >> print(isKnownUniquelyReferenced(&values._storageReference)) // false >> >> Why is the second check false, even if the property is marked as unowned >> for the view? >> >> Next up, I don’t have an idea how to correctly COW optimize this view. >> Assume the following scenario: >> >> Scenario A: >> >> var document = Document() >> >> // just assume we already added some values and can mutate safely on a given >> index >> // mutation in place >> document.values[0] = 10 >> >> VS: >> >> Scenario B: >> >> var document = Document() >> >> let copy = document >> >> // just assume we already added some values and can mutate safely on a given >> index >> // mutation in place >> document.values[0] = 10 // <--- this should only mutate `document` but not >> `copy` >> >> We could change the subscript setter on the mutable view like this: >> >> set { >> >> if !isKnownUniquelyReferenced(&self._storageReference) { >> >> self._storageReference = ... // clone >> } >> self._storageReference.values[position] = newValue >> } >> >> There is only one problem here. We’d end up cloning the storage every >> time, because as shown in the very first example, even with unowned the >> function isKnownUniquelyReferenced will return false for scenario A. >> >> Any suggestions? >> >> PS: In general I also wouldn’t want to use unowned because the view >> should be able to outlive it’s parent. >> >> >> -- >> Adrian Zubarev >> Sent with Airmail >> >> _______________________________________________ >> swift-users mailing list >> swift-users@swift.org >> https://lists.swift.org/mailman/listinfo/swift-users >> >> >
_______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users