0

我正在弄清楚 Swift 中的属性包装器,但我似乎错过了一些东西。

这就是我为我们使用的依赖注入框架编写属性包装器的方式:

@propertyWrapper
struct Inject<Value> {
    var _value: Value

    var wrappedValue: Value {
        get {
            return _value
        }
        set {
            _value = newValue
        }
    }

    init(_ container: Container = AppContainer.shared) {
        do {
            _value = try container.resolve(Value.self)
        } catch let e {
            fatalError(e.localizedDescription)
        }
    }
}

但是当我在下面的类中使用它时,会出现编译错误。我看过很多例子,对我来说做完全相同的事情,但可能存在一些差异。

class X: UIViewController {
    @Inject var config: AppConfiguration

    ....

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        config.johnDoSomething() // Compile error: 'AppConfiguration' is not convertible to 'AppConfiguration?'
    }
}

几天前,我遇到了 Xcode 在通用属性包装器方面存在编译问题的参考资料,但我再也找不到它了。我不确定这是否相关,但也许有人可以帮助我。

使用 Xcode 11.3.1

根据要求,特此声明(操场上的一个文件):

import UIKit

/// This class is only to mimick the behaviour of our Dependency Injection framework.
class AppContainer {
    static let shared = AppContainer()

    var index: [Any] = ["StackOverflow"]

    func resolve<T>(_ type: T.Type) -> T {
        return index.first(where: { $0 as? T != nil }) as! T
    }
}

/// Definition of the Property Wrapper.
@propertyWrapper
struct Inject<Value> {
    var _value: Value

    var wrappedValue: Value {
        get {
            return _value
        }
        set {
            _value = newValue
        }
    }

    init(_ container: AppContainer = AppContainer.shared) {
        _value = container.resolve(Value.self)
    }
}

/// A very minimal case where the compile error occurs.
class X {
    @Inject var text: String

    init() { }
}
4

1 回答 1

1

只是处理你的“reprex”:

改变

@Inject var text: String

@Inject() var text: String
于 2020-01-21T15:17:49.760 回答