【问题标题】:Alternative to implicitly unwrapped optional using @propertyWrapper in swift在 swift 中使用 @propertyWrapper 替代隐式解包可选
【发布时间】:2021-05-07 11:40:04
【问题描述】:

当初始化程序注入不起作用或创建 mvvm 模块时,我发现自己使用了很多 隐式解包选项

class TodoView: UIViewController {
    
    var viewModel: TodoViewModelProtocol!

}

不仅看起来不太好,而且总是强制解包如果我需要在显式解包的可选变量上使用 switch 语句也是一种痛苦。

有什么方法可以摆脱隐式展开的可选项,例如在 swift 5 中使用 @properyWrapper

【问题讨论】:

  • 切换到依赖注入是一个可行选项的 SwiftUI。此外,如果您不使用 Storyboard,则可以对 UIViewController 子类使用依赖注入。但是,对于UIViews,没有办法创建自定义初始化程序,因此无法正确使用依赖注入。
  • 那么您如何在示例中分配属性?
  • 感谢您的评论! swiftUI 看起来很有前途,我会检查它!目前我正在使用“builder”类分配每个属性。

标签: swift mvvm dependency-injection optional property-wrapper


【解决方案1】:

您可以使用属性包装器模拟隐式展开的选项,如下所示:

@propertyWrapper
struct MaybeUninitialized<T> {
    private var storage: T?
    var wrappedValue: T {
    get { storage! }
    set { storage = newValue}
    }
}

然后,您甚至可以使用可能未初始化的字段来存储可选项,而不会意外打开可选项。像这样的:

@MaybeUninitialized var x: Int?

print(x) // will crash
x = nil
print(x) // print nil

【讨论】:

  • 非常感谢,这正是我想要的,我认为它非常好!我该如何处理变量需要变弱的情况?
  • 如何创建一个使用 private weak var storage: T? 的属性包装器 (struct WeakMaybeUninitialized&lt;T: AnyObject&gt;) 的变体?这有一个很好的副作用,即弱场所需的可选项也会自动展开。
  • 非常感谢,我按照您说的进行了尝试,但是当我将其应用于协议时,出现错误“属性类型 'SomeProtocol 与其包装器类型的 'wrappedValue' 属性不匹配” 'WeakMaybeUninitialized'" 即使 SomeProtocol 符合 AnyObject。你知道发生了什么吗?这将非常有帮助!
  • 例如,如果我有协议 SomeProtocol: AnyObject {} 这有效:weak var test: SomeProtocol?但这不起作用并返回上面的错误:@WeakMaybeUninitialized var test: SomeProtocol
  • 不幸的是,将协议用作类型会导致类型不符合任何协议,包括 AnyObject。因此,我知道使用协议类型进行这项工作的唯一方法是使用动态转换:@propertyWrapper struct WeakMaybeUninitialized&lt;T&gt; { private weak var storage: AnyObject? = nil var wrappedValue: T { get { storage! as! T } set { storage = newValue as! AnyObject} } }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-24
  • 2015-10-24
  • 2020-04-05
  • 1970-01-01
  • 2014-07-23
  • 1970-01-01
相关资源
最近更新 更多