简体   繁体   English

如何使我的ReferenceWritableKeyPath类通用

[英]How to make my ReferenceWritableKeyPath class generic

I am using ReferenceWritableKeyPath to modify properties in a model class. 我正在使用ReferenceWritableKeyPath修改模型类中的属性。 This works fine, however, I now want to make my code a bit more generic so that I can modify properties from different classes. 效果很好,但是,我现在想使代码更通用,以便可以修改不同类的属性。

Here is my current code: 这是我当前的代码:

final class MyListener {
    private let reference: String
    private var listener: DatabaseHandle?
    private let backendClient: BackendClient
    private weak var model: MyModel?

    func listenToAndUpdate<T>(_ property: ReferenceWritableKeyPath<MyModel, T?>) {
        guard listener == nil else {
            return
        }
        listener = backendClient.listenToRtdbProperty(reference) { [weak self] (result: Result<T, RequestError>) in
            switch result {
            case .success(let value):
                self?.model?[keyPath: property] = value
            case .failure:
                self?.model?[keyPath: property] = nil
            }
        }
    }
}

I essentially need to have something generic in the model property, but also in the Root of the ReferenceWritableKeyPath . 我本质上需要在model属性中有一些通用的东西,在ReferenceWritableKeyPathRoot中也需要有一些通用的东西。 How can I do this? 我怎样才能做到这一点? I tried using generics on the class but it wouldn't allow me to have a weak reference to a generic property. 我尝试在类上使用泛型,但不允许我对泛型属性进行weak引用。

You were on the right track by making the MyListener class generic, but you also need to put a type constraint on the generic type to ensure that it can only be a class, which can have a weak reference. 通过使MyListener类成为泛型,您可以MyListener正确的路,但是您还需要对泛型类型施加类型约束,以确保它只能是一个类,而该类可以具有弱引用。 All classes conform to AnyObject , so it is a sufficient type constraint for your case. 所有类均符合AnyObject ,因此对于您的情况AnyObject ,这是一个足够的类型约束。

final class MyListener<Model: AnyObject> {
    private let reference: String
    private var listener: DatabaseHandle?
    private let backendClient: BackendClient
    private weak var model: Model?

    func listenToAndUpdate<T>(_ property: ReferenceWritableKeyPath<Model, T?>) {
        guard listener == nil else {
            return
        }
        listener = backendClient.listenToRtdbProperty(reference) { [weak self] (result: Result<T, RequestError>) in
            switch result {
            case .success(let value):
                self?.model?[keyPath: property] = value
            case .failure:
                self?.model?[keyPath: property] = nil
            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM