【问题标题】:Extension struct imported from C从 C 导入的扩展结构
【发布时间】:2018-09-25 23:35:14
【问题描述】:

我是 Swift 新手,我有这个扩展:

extension UIView.KeyframeAnimationOptions {
    init(animationOptions: UIView.AnimationOptions) {
        rawValue = animationOptions.rawValue
    }
}

从 Swift 4.2 开始,rawValue = animationOptions.rawValue 会产生这个警告:

Initializer for struct 'UIView.KeyframeAnimationOptions' must use "self.init(...)" or "self = ..." because the struct was imported from C

我使用这样的扩展:

UIView.animateKeyframes(withDuration: 1.2, delay: 0.0, options: [.repeat, UIView.KeyframeAnimationOptions(animationOptions: .curveEaseOut)], animations: {
...
}

如何解决来自struct was imported from C 的警告消息?

【问题讨论】:

  • 为什么要尝试从UIView.AnimationOptions 类型的值创建UIView.KeyframeAnimationOptions?那是不合适的。它们是不同的类型,具有不同的用途。

标签: swift swift4.2


【解决方案1】:

这样做的目的是限制跨模块的结构初始化器。这加强了初始化结构的安全性。

Swift 结构被设计为灵活的,它们的实现 可以在版本之间更改。由于初始化程序必须 初始化每个存储的属性,它们有两个选项:

  • 在返回或使用 self 之前分配每个属性。
  • 使用self.init(…)self = … 一次性分配所有属性。

前者需要知道结构中的每个存储属性。如果 所有这些属性恰好都是公开的,但是, 另一个目标可以实现自己的初始化程序,然后突然 添加新的存储属性(公共或非公共)成为破坏源 改变。

你可以在这里here找到更多细节。

Swift 4.1 开始,您的代码应如下所示:

extension UIView.KeyframeAnimationOptions {
    init(animationOptions: UIView.AnimationOptions) {
        self = .init(rawValue: animationOptions.rawValue)
    }
}

【讨论】:

  • 感谢您的解释。两个答案代码运行良好。
【解决方案2】:

您的代码从来都不正确。应该是:

extension UIView.KeyframeAnimationOptions {
    init(animationOptions: UIView.AnimationOptions) {
        self.init(rawValue: animationOptions.rawValue)
    }
}

但是,这是个坏主意。您将一个枚举的选项强制转换为一个不相关的枚举。这会导致问题。

【讨论】:

    猜你喜欢
    • 2014-08-22
    • 1970-01-01
    • 2015-04-21
    • 1970-01-01
    • 2014-04-08
    • 2016-06-22
    • 2015-08-05
    • 1970-01-01
    相关资源
    最近更新 更多