无需移除的KVOApi-iOS,一行代码block回调
2021-09-28 本文已影响0人
不拘小节123456
新版kvoblock回调虽然不需要移除操作,但是需要增加很多成员变量,通过关联对象技术,给监听对象动态添加了一个map来持有这些对象
KCKVOObserverProtocol实现改协议
//调用api
addKVOObserver(target: btn, keyPath: "frame", option: [.new,.old]) { (change) in
print("change -----\(change)")
}
//具体实现
//
// KVO+Tool.swift
// KCNotificationCenterTool
//
// Created by FanQiLe on 2021/9/28.
//
import UIKit
private var kvoTokensKey = "KCKVOObserverProtocol"
public protocol KCKVOObserverProtocol: NSObjectProtocol {}
public typealias KVOBlock = (([NSKeyValueChangeKey : Any]) -> ())
class KCKVOItemObj: NSObject {
var block:KVOBlock?
var target:NSObject?
var keyPath: String?
class func createOBj(target:NSObject,keyPath:String,option:NSKeyValueObservingOptions,block:KVOBlock?) -> KCKVOItemObj {
let temp = KCKVOItemObj()
temp.target = target
temp.keyPath = keyPath
temp.block = block
target.addObserver(temp, forKeyPath: keyPath, options: option, context: nil)
return temp
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
self.block?(change ?? [:])
}
deinit {
self.target?.removeObserver(self, forKeyPath: self.keyPath ?? "")
}
}
extension KCKVOObserverProtocol {
public func addKVOObserver(target:NSObject,keyPath:String,option:NSKeyValueObservingOptions,block:KVOBlock?) {
var tokens = getTokens()
let obj = KCKVOItemObj.createOBj(target: target, keyPath: keyPath, option: option, block: block)
let objStr = String(describing: target.self)
tokens["\(objStr)\(keyPath)"] = obj;
setTokens(tokens)
}
private func getTokens() -> [String: KCKVOItemObj] {
synchronized(self) {
if let observers = objc_getAssociatedObject(self, &kvoTokensKey) as? [String: KCKVOItemObj] {
return observers
}
return [String: KCKVOItemObj]()
}
}
private func setTokens(_ tokens: [String: KCKVOItemObj]) {
synchronized(self) {
objc_setAssociatedObject(self, &kvoTokensKey, tokens, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
}
demo请看下面
https://github.com/riceForChina/NotificationCenter-Tool.git