generics - Set of weak observers in Swift -
i trying implement structure allows me store set of weak observers.
here observer wrapper:
public func ==<t: hashable>(lhs: weakobserver<t>, rhs: weakobserver<t>) -> bool { return lhs.hashvalue == rhs.hashvalue } public struct weakobserver<t t: anyobject, t: hashable> : hashable { private weak var weakobserver : t? public init(weakobserver: t){ self.weakobserver = weakobserver } public var hashvalue : int { return self.weakobserver!.hashvalue } }
and here protocol every observer needs conform to:
public protocol datamodelobserverprotocol : class, hashable, anyobject { func somefunc() }
usage:
public class datamodel: nsobject, datamodelinterface { public var observers = set<weakobserver<datamodelobserverprotocol>>() //^^^^^ using 'datamodelobserverprotocol' concrete type conforming protocol 'anyobject' not supported }
now, while aware might limitation swift itself, looking alternative solution without having concrete class type constraint (if that's not possible, afraid case, i'd still love alternative "non-hacky" solutions).
using set hold references runs risk set need reference element using hashvalue and, when weak reference goes nil, hashvalue function crash.
i couldn't protocols found way similar functionality using generic function returns 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, use:
observers.addobject( yourobserver )
to iterate through observers :
for observer in observers.objects() { observer.somefunc() }
both functions type safe , accept/return datamodelobserverprotocol compliant objects
Comments
Post a Comment