Home > Blockchain >  Can I use RunLoop for realtime object observing in Swift?
Can I use RunLoop for realtime object observing in Swift?

Time:09-12

I have a Process object (is kind of Model). Inside a process, I have an array of tuples

var listeners: [(WeakContainer<AnyObject>, (S) -> ())]

WeakContainer handles a weak ref inside. I need to remove an element from the listeners array when Conainer's value becomes nil. My code looks like this:

class Process<S> {
    
    typealias Handler = (S) -> ()
    typealias Listener = (container: Weak<AnyObject>, handler: StateHandler)
    
    var listeners: [Listener] = []
    private let runLoop = RunLoop()
    
    init() {
        runLoop.run(mode: .default, before: .now)
        runLoop.perform { [weak self] in
            self?.state.listeners.removeAll {
                $0.container.value == nil
            }
        }
    }
    
}

Is it correct usage of RunLoop for my targets or not? Why? I will be grateful if you propose a more suitable alternative for my case (tracking for the object becomes nil).

CodePudding user response:

There is a NSMapTable collection which is flexible for configuring with various memory retaining policy.

Here is an example how to store Handler object with a weak key object. Handler will be retained until key exist, and the pair will be removed from the collection on key delete.

class Handler<Action> {
    let action: Action
    init(_ action: Action) {
        self.action = action
    }
}

var listeners = NSMapTable<AnyObject, Handler<(S)->Void>> (keyOptions: [.weakMemory, .objectPointerPersonality],
                                                           valueOptions: .strongMemory)
  • Related