Is a "callback" intended as "single job executed upon deallocation"? In that case, multiple subjects might be interested in this event.
My current design for the WeakDictionary is considering the fact that in a WeakCollection you might store fairly heavy objects that you want to clear from memory as soon as they are no longer needed.
The problem is relatively small while talking about WeakArray because what remains in memory is the container. but for WeakDictionary the story is fairly different because of the patterns they enable.
Example: Hash Consing or Flyweight patterns.
Imagine a Coordinator pattern; The coordinator generates the ViewController (and all the stack to keep the VC functional), then returns it. The coordinator keeps a weak reference to the generated VC.
The parent coordinator stores in a WeakDictionary the viewController as weak key and the coordinator that generated it as value (the same coordinator might build 2 different VC and you want to keep it alive for as long as at least one VC it generated is on alive).
The coordinator is implicitly retained by the VC, the VC is retained by UIKit and it will stay alive for as long as it stays on the screen. When the VC is dismissed I expect the Coordinator to die as well. In this case, the coordinator might be a fairly heavy object that still will not cause memory pressure, and the nature of the design pattern might never cause a resize of the data structure, so this memory is in all sense a memory leak.
True Flyweight/Hash consing in swift is currently not possible. The closest thing I had to make it work is having this extra O(n) work to clean up on access. A real-time "dead" notification would be amazing.