首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Swift 4中的KVObserving协议

Swift 4中的KVObserving协议
EN

Stack Overflow用户
提问于 2017-11-09 10:51:46
回答 1查看 1.6K关注 0票数 15

我很难使用Swift 4中新的强类型KVO语法来观察只能通过协议可见的属性:

代码语言:javascript
复制
import Cocoa

@objc protocol Observable: class {
    var bar: Int { get }
}

@objc class Foo: NSObject, Observable {
    @objc dynamic var bar = 42
}

let implementation = Foo()

let observable: Observable = implementation

let observation = observable.observe(\.bar, options: .new) { _, change in
    guard let newValue = change.newValue else { return }

    print(newValue)
}

implementation.bar = 50
代码语言:javascript
复制
error: value of type 'Observable' has no member 'observe'
let observation = observable.observe(\.bar, options: .new) { _, change in

显然,Observable不是NSObject。但我不能简单地将其转换为NSObject,因为键盘的类型将与对象的类型不匹配。

我试着更明确地说明这种类型:

代码语言:javascript
复制
let observable: NSObject & Observable = implementation

但是:

代码语言:javascript
复制
error: member 'observe' cannot be used on value of protocol type 'NSObject & Observable'; use a generic constraint instead
let observation = observable.observe(\.bar, options: .new) { _, change in

我想做的是不可能的吗?这似乎是一个常见的用例。用旧的#keypath语法可以很容易地完成。你能提供其他选择吗?谢谢。

EN

回答 1

Stack Overflow用户

发布于 2018-06-01 14:50:46

这段代码在Swift 4.1.2 (Xcode 9.4)中编译和运行:

代码语言:javascript
复制
import Foundation

@objc protocol Observable: AnyObject {
    var bar: Int { get }
}

@objc class Foo: NSObject, Observable {
    @objc dynamic var bar = 42
}

let implementation = Foo()

let observable: NSObject & Observable = implementation

func observeWrapper<T: NSObject & Observable>(_ object: T) -> NSKeyValueObservation {
    return object.observe(\.bar, options: .new) { _, change in
        guard let newValue = change.newValue else { return }
        print(newValue)
    }
}

let observation = observeWrapper(observable)
implementation.bar = 50
withExtendedLifetime(observation, {})

我所做的就是将对observe的调用封装在一个受限于NSObject & Observable的泛型函数中。

尽管引入了泛型,但仍然可以将协议类型的observable传递给这个新函数。老实说,我不能真正解释为什么会这样。

编辑:这可能解释为:https://stackoverflow.com/a/43408193/116862,因此即使约束匹配,也不允许调用具有存在性(协议类型)的泛型函数。但是@objc协议有一个例外(没有静态需求),它们确实符合自己的要求。我认为这是因为Observable被标记为@objc__。

票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47199946

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档