I am trying to implement the multicast delegate functionality in Swift. In Objective C, we have this excellent implementation
https://github.com/robbiehanson/XMPPFramework/blob/master/Utilities/GCDMulticastDelegate.m
And I have just created this basic functionality:
protocol MyProtocol : class{
func testString()-> String;
}
class MulticastDelegateNode <T:AnyObject> {
weak var delegate : T?
init(object : T){
self.delegate = object;
}
}
class MulticastDelegate <T:AnyObject> {
var delegates = Array<MulticastDelegateNode<T>>()
func addDelegate(delegate : T){
var newNode = MulticastDelegateNode(object : delegate);
delegates.append(newNode);
}
func removeDelegate(delegate : AnyObject){
self.delegates = self.delegates.filter({ (node : MulticastDelegateNode) -> Bool in
return node.delegate !== delegate;
});
}
}
class OP {
var delegate = MulticastDelegate<MyProtocol>();
func process(){
//...
//make actions
//notify the objects!
}
}
My problem is that it seems I cannot figure out a way to do this:
delegate.testString()
In order to give the command 'testString()' to all delegates that are in the nodes. Can anyone help me with this?
Here is my implementation of multicast delegate using Swift 2.0 protocol extensions. Also i've added ability to remove delegates. To do so I've made my delegate type conform to NSObjectProtocol, didn't get how to declare that it should be reference type to use === operator for remove.
and here is example of usage
Swift 3 implementation:
You can test it with:
It prints:
Based on this blog post.
Ok. In some of the solutions I see mistakes (strong retain cycles, race conditions, ...)
Here is what I combine based on 1 day research. For the stack of delegates I used NSHashTable, so all the delegates are having weak reference.
Swift 3.1
How to set delegate:
How to execute function on the delegates: instead of
you use
I've added my implementation of a Swift multicast delegate on GitHub: https://github.com/tumtumtum/SwiftMulticastDelegate
Basically you use the overloaded operator "=>" with a block to perform the invocation. Internally the MulticastDelegate will call that block for every listener.
A Simple demo about MulticastDelegate.
You might be able to add
To your protocol & classes, of course then you are no longer doing pure swift ... but that might solve your issue as it will re-enable dynamic dispatch powers.