我有一个“updateBlocks”(闭包)数组,在单例类中使用它在数据更新时通知任何观察者(UIViewControllers等)。
我想知道移除观察者的最佳方法是什么,这样当观察者被释放(或者不再需要更新)时,它就不会被执行。
这是我当前的设置:
MySingleton类

var updateBlock: (() -> ())? {
    didSet {
        self.updateBlocks.append(updateBlock!)
        self.updateBlock!() // Call immediately to give initial data
    }
}
var updateBlocks = [() -> ()]()

func executeUpdateBlocks() {
    for block in updateBlocks {
        block()
    }
}

MyObserver类
MySingleton.shared.updateBlock = {
    ...handle updated data...
}

MySingleton.shared.updateBlock = nil // How to properly remove???

最佳答案

你的单件设计有些问题。
updateBlock作为didSet方法的变量添加到updateBlocks数组中是错误的设计。
我建议去掉updateBlock变量,而是定义一个addUpdateBlock方法和一个removeAllUpdateBlocks方法:

func addUpdateBlock(_ block () -> ()) {
   updateBlocks.append(block)
}

func removeAllUpdateBlocks() {
   updateBlocks.removeAll()
}
func executeUpdateBlocks() {
    for block in updateBlocks {
        block()
    }

}
如果你想删除单个块,那么你需要一些方法来跟踪它们。正如rmaddy所说,每个街区都需要某种身份证。您可以重构容器,使块成为字典,并使用顺序整数键。添加新块时,addBlock函数可以返回键:
var updateBlocks = [Int: () -> ()]()
var nextBlockID: Int = 0

func addUpdateBlock(_ block () -> ()) -> Int {
   updateBlocks[nextBlockID] = block
   let result = nextBlockID
   nextBlockID += 1

   //Return the block ID of the newly added block
   return result
}

func removeAllUpdateBlocks() {
   updateBlocks.removeAll()
}

func removeBlock(id: Int) -> Bool {
   if updateBlocks[id] == nil {
     return false
   } else {
     updateBlocks[id] = nil
     return true
   }

func executeUpdateBlocks() {
    for (_, block) in updateBlocks {
        block()
    }

如果将块保存在字典中,则它们不会按任何定义的顺序执行。

08-27 05:09