美文网首页
无需移除的KVOApi-iOS,一行代码block回调

无需移除的KVOApi-iOS,一行代码block回调

作者: 不拘小节123456 | 来源:发表于2021-09-28 15:46 被阅读0次

新版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

相关文章

  • 无需移除的KVOApi-iOS,一行代码block回调

    新版kvoblock回调虽然不需要移除操作,但是需要增加很多成员变量,通过关联对象技术,给监听对象动态添加了一个m...

  • block 的使用 (一)

    iOS 三大回调方式:目标动作回调,委托回调,代码块回调,喜欢 block 是因为他很简洁紧凑,代码可读性高。 b...

  • iOS中block的用法

    定义block类型 定义block块,代码更清新 函数中定义block回调的方法 持续补充中......

  • UI(二十)block

    *block代码块 闭包(一个区域)与C语言函数类似 *block具有反向传值、回调的功能 回调:执行完毕之后返回...

  • iOS - block

    *block代码块闭包(一个区域)与C语言函数类似 *block具有反向传值、回调的功能 回调:执行完毕之后返回再...

  • Objective-C-(三) Block实现解析

    最近研究了下Block的实现代码,解惑了以前一直好奇的Block捕获外部变量,__block,Block回调等特性...

  • 关于block

    block是在iOS 4.0之后出现的,封装了一段代码并将这段代码当做变量,通过block()的方式进行回调,说白...

  • iOS 开发之Block

    ios4.0之后,block横空出世,它本身封装了一段代码并将这段代码当做变量,通过block()的方式进行回调....

  • iOS开发通话状态

    通过CTCall 的callEventHandler回调block来获得通话状态的改变. 代码如下: sim卡问题...

  • 认识下OC中的Block,常见的一些误区

    Block是什么: 我们可以认为是一段代码并可以将这段代码当做变量,通过block()的方式进行回调。这不免让我们...

网友评论

      本文标题:无需移除的KVOApi-iOS,一行代码block回调

      本文链接:https://www.haomeiwen.com/subject/dohrnltx.html