[swift-evolution] Proposal: Weak Native Swift Containers

John McCall rjmccall at apple.com
Thu Dec 10 18:08:08 CST 2015


> On Dec 10, 2015, at 3:31 PM, Riley Testut via swift-evolution <swift-evolution at swift.org> wrote:
> Using box types solves the portability problems, but it still means O(n) access for clients who want to access the non-boxed values directly. Additionally, these objects aren’t automatically removed from the collection when their values are nil-ed out, which is unfortunate.
> 
> Side note: this is the route I originally tried to take, but unfortunately the Swift doesn’t work well with weak references to protocol types…

Really?  Please file a bug about this; I’ve been working in this area recently.

(Or just point out the radar number if you filed one there already.)

John.

> 
>> On Dec 10, 2015, at 3:01 PM, Tommy van der Vorst <tommy at pixelspark.nl <mailto:tommy at pixelspark.nl>> wrote:
>> 
>> Hi Riley,
>> 
>> Have you tried using an array of structs that in turn hold weak references to your objects? Something like this should work:
>> 
>> public class Weak<T: AnyObject>: NSObject {
>> 	public private(set) weak var value: T?
>> 
>> 	public init(_ value: T?) {
>> 		self.value = value
>> 	}
>> }
>> 
>> let weakFoo: [Weak<Foo>] = [Weak<Foo>(foo), ...]
>> 
>> Comes with the overhead of one extra object instantiated per element, but perhaps this is acceptable for your use case.
>> 
>> /T
>> 
>>> Op 10 dec. 2015, om 23:55 heeft Riley Testut via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> het volgende geschreven:
>>> 
>>> 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?
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 
> 
>  _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151210/af7add43/attachment-0001.html>


More information about the swift-evolution mailing list