[swift-evolution] Re-Visit Proposal: Weak Native Swift Containers (12 2015)
Patrick Smith
pgwsmith at gmail.com
Wed May 11 08:30:06 CDT 2016
I remember reading that Swift’s weak references are ‘lazy’, and only clear (and release if needed) when they are next accessed. So you couldn’t observe them AFAIK.
> On 11 May 2016, at 11:23 PM, Haravikk via swift-evolution <swift-evolution at swift.org> wrote:
>
> I’ve used the following in some similar cases:
>
> struct Weak<T> {
> weak var value:T?
> init(_ value:T) { self.value = value }
> }
> let myCache = Array<Weak<Foo>>()
>
> When inserting new values I just look for the first one that’s nil or append if it’s taking too long, but you’re right, something more reactive would be better, for example if the above were observable I could do something about it as soon as it became nil.
>
>> On 11 May 2016, at 14:00, Dominik Pich via swift-evolution <swift-evolution at swift.org> wrote:
>>
>> Hello,
>> I'd like to re-visit a proposal from Riley Testut about weak containers. Since no conclusion/outcome was achieved (AFAICS from looking at the archives and the repository)
>> and since I just would have needed this again too... I found it a good time to re-propose this :D
>>
>> ---
>>
>> "
>> In multiple places in my projects, I essentially recreate the “multiple observer” pattern used by NSNotificationCenter. Originally this was implemented by simply maintaining an array of observers, and adding to/removing from it as necessary. However, this had the unintended side effect of maintaining a strong reference to the observers, which in many cases is undesirable (for the same reasons it’s common to mark delegate properties as weak).
>>
>> Now, I’m using a private NSHashTable instance, and expose the observers as public API by creating a public computed property which essentially returns an array derived from the NSHashTable like so:
>>
>> public var receivers: [GameControllerReceiverType] {
>> // self.privateReceivers.allObjects as! [GameControllerReceiverType] crashes Swift :(
>> return self.privateReceivers.allObjects.map({ $0 as! GameControllerReceiverType })
>> }
>>
>> This workaround works, but is undesirable for a number of reasons. Most notably:
>>
>> • NSHashTable is not a native Swift collection, and is also not in the Foundation Swift port, so it is not portable to other systems.
>> • It also has not yet been annotated with generics, so it loses the nice type safety of other Swift collections. Because of this, I have to map the objects to the appropriate type before returning the allObjects array, which runs in O(n) time instead of O(1).
>> • It’s repetitive. For every type that wants to implement this pattern, they must maintain both a public computed method and a private NSHashTable instance. This gets worse when this should be part of a protocol; there’s no way to enforce that each type conforming to it has a NSHashTable, while also keeping that information private from the consumer of the API.
>>
>> I think native swift collections with support for weak references for their contents would be very useful, and in more places than just listed above. I don’t think Array could be easily extended to support it (what happens if a value is released? does everything shift down? do they keep their indices?), but Set and Dictionary (where the keys and/or values could be weak, akin to NSMapTable) would be good candidates IMO.
>>
>> Thoughts?"
>>
>> --reference to last message thread: https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151207/001579.html
>> (last messages were 'arguing' how to implement it)
>>
>>
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
More information about the swift-evolution
mailing list