Swift Observer Set

I am trying to implement a structure that allows me to store a set of weak observers.

Here is the observer shell:

public func ==<T: Hashable>(lhs: WeakObserver<T>, rhs: WeakObserver<T>) -> Bool {
  return lhs.hashValue == rhs.hashValue
}

public struct WeakObserver<T where 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 is the protocol that every observer must comply with:

public protocol DataModelObserverProtocol : class, Hashable, AnyObject {

  func someFunc()

}

Using:

public class DataModel: NSObject, DataModelInterface {

  public var observers = Set<WeakObserver<DataModelObserverProtocol>>()
  //^^^^^ Using 'DataModelObserverProtocol' as a concrete type conforming to protocol 'AnyObject' is not supported
}

Now that I know that this may be a limitation of Swift itself, I am looking for an alternative solution without having a concrete class as a type constraint (if this is not possible, which I fear, it is so, d still like to get alternative "non-hacks " solutions).

+4
source share
2 answers

, , , -:

NSNotificationCenter , , , , . - , userInfo, .

, , - . , , - , " ".

, :

NSNotificationCenter.defaultCenter().addObserver(...)

:

NSNotificationCenter.defaultCenter().postNotification...

NSNotificationCenter , , , WeakSet.

, , ( , , , ). , , , WeakSet, . (, ), .

0

Set , Set , hashValue, , , hashValue .

, , , .

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)
}

, :

observers.addObject( yourObserver )

:

for observer in observers.objects()
{
   observer.someFunc()
}

/ , DataModelObserverProtocol.

+2

Source: https://habr.com/ru/post/1624578/


All Articles