[swift-evolution] Re-Visit Proposal: Weak Native Swift Containers (12 2015)

dominik at pich.info dominik at pich.info
Wed May 11 08:00:13 CDT 2016

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.


--reference to last message thread:  
(last messages were 'arguing' how to implement it)

More information about the swift-evolution mailing list