jjzjj

swift - KVO : How to get old/new values in observeValue(forKeyPath:. ..) 在 Swift 中?

coder 2023-09-04 原文

我用 .Old | 创建了一个观察者.新的 选项。在处理程序方法中,我尝试获取前后值,但编译器提示:'NSString' is not convertible to 'NSDictionaryIndex: NSObject, AnyObject

override func observeValueForKeyPath(keyPath: String!, ofObject object: AnyObject!, change: [NSObject : AnyObject]!, context: UnsafeMutablePointer<Void>) {

    let approvedOld = change[NSKeyValueChangeOldKey] as Bool
    let approvedNew = change[NSKeyValueChangeNewKey] as Bool

最佳答案

iOS 11 和 Swift >4.1

iOS 11 和 Swift 4 为 KVO 带来了重大变化。

  • 类应该采用@objcMembers注解,以启用KVO或KVO静默失败。
  • 要观察的变量必须声明为dynamic

这是较新的实现,

@objcMembers
class Approval: NSObject {

    dynamic var approved: Bool = false

    let ApprovalObservingContext = UnsafeMutableRawPointer(bitPattern: 1)

    override init() {
        super.init()

        addObserver(self,
                    forKeyPath: #keyPath(approved),
                    options: [.new, .old],
                    context: ApprovalObservingContext)
    }

    override func observeValue(forKeyPath keyPath: String?,
                               of object: Any?,
                               change: [NSKeyValueChangeKey : Any]?,
                               context: UnsafeMutableRawPointer?) {
        guard let observingContext = context,
            observingContext == ApprovalObservingContext else {
                super.observeValue(forKeyPath: keyPath,
                                   of: object,
                                   change: change,
                                   context: context)
                return
        }

        guard let change = change else {
            return
        }

        if let oldValue = change[.oldKey] {
            print("Old value \(oldValue)")
        }

        if let newValue = change[.newKey]  {
            print("New value \(newValue)")
        }

    }

    deinit {
        removeObserver(self, forKeyPath: #keyPath(approved))
    }
}

KVO 也有新的基于 bock 的 api,它是这样工作的,

@objcMembers
class Approval: NSObject {

    dynamic var approved: Bool = false

    var approvalObserver: NSKeyValueObservation!

    override init() {
        super.init()
        approvalObserver = observe(\.approved, options: [.new, .old]) { _, change in
            if let newValue = change.newValue {
                print("New value is \(newValue)")
            }

            if let oldValue = change.oldValue {
                print("Old value is \(oldValue)")
            }
        }

    }
}

基于 block 的 api 看起来 super 好用。此外,KeyValueObservation 在 deinited 时失效,因此没有删除观察者的硬性要求。

Swift 2.0 和 iOS <>

在 Swift 2.0 中,这是一个使用 KVO 的类的完整实现,

 class Approval: NSObject {

    dynamic var approved: Bool = false

    let ApprovalObservingContext = UnsafeMutablePointer<Int>(bitPattern: 1)

    override init() {
        super.init()
        addObserver(self, forKeyPath: "approved", options: [.Old, .New], context: ApprovalObservingContext)
    }

    override func observeValueForKeyPath(keyPath: String?,
                                         ofObject object: AnyObject?,
                                                  change: [String : AnyObject]?,
                                                  context: UnsafeMutablePointer<Void>) {

        if let theChange = change as? [String: Bool] {

            if let approvedOld = theChange[NSKeyValueChangeOldKey]  {
                print("Old value \(approvedOld)")
            }

            if let approvedNew = theChange[NSKeyValueChangeNewKey]{
                print("New value \(approvedNew)")

            }

            return
        }
        super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context)
    }

    deinit {
        removeObserver(self, forKeyPath: "approved")
    }
}

let a  = Approval()
a.approved = true

关于swift - KVO : How to get old/new values in observeValue(forKeyPath:. ..) 在 Swift 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25958985/

有关swift - KVO : How to get old/new values in observeValue(forKeyPath:. ..) 在 Swift 中?的更多相关文章

  1. swift - 将 json 编码时间转换为 nsdate - 2

    当我将time.Now()编码到JSON对象时,它给出的结果为"2009-11-10T23:00:00Z"但打印时间。现在给出2009-11-1023:00:00+0000UTC。他们为什么不同。什么是T和Z。另外,如何根据this将其转换为swiftNSDate对象?表? 最佳答案 这些值的含义无关紧要,它们是该格式(ISO8601)的一部分。有几种方法可以解决这个问题。一种是为时间或您的结构定义自定义MarshalJSON()方法并使用它来格式化日期,另一种是首先在您的结构中将其表示为字符串,以便当默认实现执行你得到你正在寻找的

  2. objective-c - 为什么 Swift 函数定义语法是多余的? - 2

    在C/C++/Java/Go中,我们使用,来分隔参数:(aint,bint)在ObjectiveC中,我们使用:来表示参数::(int)a:(int)b在Swift中,我们必须同时使用:和,:(a:int,b:int)是否需要冗余? 最佳答案 Swift可能有外部和内部参数名称:(externalinternal:Int)如果没有独特的分隔符,会产生很多歧义。 关于objective-c-为什么Swift函数定义语法是多余的?,我们在StackOverflow上找到一个类似的问题:

  3. swift - Swift 和 Go 之间的 Zlib 压缩 - 2

    我的Swift应用程序与用Go编写的服务器通信。我希望使用Zlib压缩传输的数据,但压缩结果似乎与Swift和Go不同。这是Go版本:sourceString:="A-t-ellebesoind'autrespreuves?Acceptez-lapourleplaisir.J'aitantfaitquedelacueillir,Etc'estpresqueunefleur-des-veuves."//Compressionvarbbytes.Bufferwriter:=zlib.NewWriter(&b)writer.Write([]byte(sourceString))writer.

  4. ios - swift api SecKeyCreateEncryptedData 使用的额外认证数据是什么? - 2

    我正在使用rsaEncryptionOAEPSHA256AESGCM在iOS上使用SecKeyCreateEncryptedData加密一些数据,然后在golang后端解密相同的数据。我正在使用3072位rsa公钥来加密对称key。当我从iOS获取数据到后端时,我能够成功解密对称key,但gcm标签验证失败。我使用的是与iOS相同的16字节IV,但不知道iOS在加密时是否使用任何aad(附加身份验证数据)。有谁知道rsaEncryptionOAEPSHA256AESGCMforiOS是否使用了一些aad?这适用于iOS10+。我已经尝试过使用nil、空的16字节数组、aeskey本身、

  5. json - 如何使用 iOS Swift 访问设备中的 vpn api url? - 2

    我使用swiftyJSON从apiurl消费OData。这里的apiurl与VPN连接。并且apiurl看起来像http://192.xxx.xx.xx:8000/sap/opu/odata/sap/Z_SRV/PRListSetSet?$format=json当我在模拟器中运行时,我可以从odataapiurl获取数据,但是在设备中运行时,没有从odataapiurl接收到数据。由于没有vpn连接到移动设备。我如何以编程方式对我的VPN进行硬编码以在移动设备中接收数据?这是我如何从ODataapiurl获取数据:typealiasServiceResponse=(JSON,Error

  6. xml - 使用 XML 解析 Swift 库时,Playgrounds 崩溃并显示 "unknown error" - 2

    我正在开发一个涉及一些XML解析的自定义框架,使用Kanna框架。每当我尝试将我的框架导入playground时,playground就会崩溃并出现以下错误:Playgroundexecutionfailed:expressionfailedtoparse,unknownerror*thread#1:tid=0x4e9448,0x00000001074bf360com.apple.dt.Xcode.PlaygroundStub-macosx`executePlayground,queue='com.apple.main-thread',stopreason=breakpoint1.1*

  7. swift - 在 Windows 10 上的 Ubuntu 上的 bash 上安装 swift 4 - 2

    我尝试在Windows10上的Ubuntu上的bash上安装Swift4我的Ubuntu版本:我@DESKTOP:~$lsb_release-a没有可用的LSB模块。经销商ID:Ubuntu描述:Ubuntu16.04.3LTS发布:16.04代号:xenial我做了apt-getupgrade和apt-getupdate我遵循Linux步骤here:安装Swift4最终我得到了错误:我@DESKTOP:~$swift/home/me/swift4/swift-4.0.2-RELEASE-ubuntu16.04/usr/bin/lldb:加载共享库时出错:libpython2.7.so

  8. iOS-Swift 音视频采集与文件写入 - 2

    概述音视频采集是直播架构的第一步音视频采集包括两部分视频采集音频采集iOS开发中,同音视频采集相关API都封装在AVFoundation中,导入该框架,即可实现音频、视频的同步采集采集步骤采集步骤文字描述导入框架同采集相关API在AVFoundation中,因此需要先导入框架创建捕捉会话(AVCaptureSession)会话:用于连接输入源、输出源输入源:摄像头、麦克风输出源:对应的视频、音频数据设置视频输入源、输出源输入源(AVCaptureDeviceInput):从摄像头输入(前置/后置)输出源(AVCaptureVideoDataOutput):可从代理方法中拿到数据将输入源、输出源

  9. Swift 周报 第十六期 - 2

    前言本期是Swift编辑组自主整理周报的第七期,每个模块已初步成型。各位读者如果有好的提议,欢迎在文末留言。欢迎投稿或推荐内容。目前计划每两周周一发布,欢迎志同道合的朋友一起加入周报整理。当你来到双水村以外的大世界,你的人生目标便不单单是一名庄稼人了。Swift社区陪你一起成长,一起创造更多可能!👊👊👊周报精选新闻和社区:【挑战上岛】适配实时活动和灵动岛提案:函数反向部署Swift论坛:围绕Swift6lock展开的讨论推荐博文:推荐500+款AppUI设计工具推荐:妙言话题讨论:如果您年龄超过35岁被裁员,再入职时能接受降薪吗?新闻和社区挑战上岛:适配实时活动和灵动岛Apple大中华区设计与

  10. php - Swift Mailer 有问题不发送消息 - 2

    我的swiftmailer有问题,它没有向用户发送消息我将库提取到我网站的inc文件夹并创建了以下消息供swiftmailer发送:注意:如果您可以建议除SwiftMailer之外的其他解决方案,请发表评论。require_once'inc/lib/swift_required.php';//CreatetheTransport$transport=Swift_SmtpTransport::newInstance('mail.mywebsite.com',25)->setUsername('info@mywebsite.com')->setPassword('myPassword');

随机推荐