Set of weak observers in Swift
Using a Set to hold the references runs a risk that the Set will eventually need to reference an element using its hashValue and, when the weak reference goes nil, the hashValue function will crash.
I couldn't do it with protocols but I found a way to get a similar functionality using a generic function that returns a tuple of functions.
struct WeakReference<T>
{
weak var _reference:AnyObject?
init(_ object:T) {_reference = object as? AnyObject}
var reference:T? { return _reference as? T }
}
func weakReferences<T>(_:T.Type) -> (
getObjects: ()->[T],
addObject: (T)->()
)
{
var references : [WeakReference<T>] = []
func getObjects() -> [T]
{
return references.filter({ $0.reference != nil }).map({$0.reference!})
}
func addObject(object:T)
{
if getObjects().contains({ ($0 as! AnyObject) === (object as! AnyObject) })
{ return }
references.append(WeakReference(object))
}
return (getObjects:getObjects, addObject:addObject)
}
public protocol DataModelObserverProtocol: class, AnyObject
{
func someFunc() -> String
}
public class DataModel: NSObject, DataModelInterface
{
var observers = weakReferences(DataModelObserverProtocol)
}
To add observers, you would use:
observers.addObject( yourObserver )
To iterate through the observers :
for observer in observers.objects()
{
observer.someFunc()
}
Both functions are type safe and will only accept/return DataModelObserverProtocol compliant objects