【问题标题】:Compilation fails with valid code when "Fastest -O" optimizations are set设置“Fastest -O”优化时,编译失败并显示有效代码
【发布时间】:2015-06-30 00:44:16
【问题描述】:

以下代码是有效的 Swift 代码,并且在禁用优化时可以正确编译。

protocol Foo {
    var bar: String { get set }
}

class BaseFoo: Foo {
    var bar: String = "hello"
}

class ChildFoo: BaseFoo {
    private var _bar: String = "world"

    override var bar: String {
        get {
            return _bar
        }
        set {
            _bar = newValue
        }
    }
}

启用 Swift 优化(Fastest -O)后,我只会从 xcode 收到一条非常模糊的错误消息:

命令 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc 失败,退出代码为 1

所以我尝试运行 Xcode 说失败的命令,我能够找到更有趣的错误:

PHINode 应该为其父基本块的每个前任都有一个条目!
%11 = phi i64 [ %43, %33 ], [ 0, %29 ], !dbg !747
LLVM 错误:发现损坏的函数,编译中止!

【问题讨论】:

    标签: ios xcode swift


    【解决方案1】:

    答案是编译器存在错误。不知何故,它在覆盖协议中定义的读写属性方面存在问题。我找不到解决方案,只有以下解决方法:

    1. 如果在协议中将该属性设为只读(通过将{ get set } 更改为{ get }),错误将消失。不幸的是,如果您无权访问实现类型,您将无法重写变量(而且您不应该这样做,否则您将失去协议带来的好处)

    2. 不要覆盖子类中的属性(在我们的例子中为ChildFoo)。如果您不覆盖它,您将不会遇到此错误。另一方面,如果您不需要这样做,您可能不会覆盖它,所以这对您没有多大帮助。

    3. 最后但并非最不重要的解决方法是为您提供覆盖支持和读写访问(嗯,有点)。将协议更改为没有变量,但有 getter 和 setter 方法。这样您就可以从外部设置值,也可以覆盖 get 或 set 的行为。

    我最终使用了第三种解决方法,因为我需要读写和覆盖支持。所以最后我的代码看起来像这样:

    protocol Foo {
        func getBar() -> String
    
        func setBar(bar: String)
    }
    
    class BaseFoo: Foo {
        private var bar: String = "hello"
    
        func getBar() -> String {
            return bar
        }
    
        func setBar(bar: String) {
            self.bar = bar
        }
    }
    
    class ChildFoo: BaseFoo {
        private var _bar: String = "world"
    
        override func getBar() -> String {
            return _bar
        }
    
        override func setBar(bar: String) {
            _bar = bar
        }
    }
    

    我填写了一份雷达报告 http://www.openradar.appspot.com/21603216,希望 Apple 能够修复它。我在 Swift 2.0 的新 Xcode nor没有尝试过这个。

    希望这对遇到同样问题的人有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-04
      • 2011-01-22
      • 1970-01-01
      • 2016-08-14
      • 2011-10-27
      • 1970-01-01
      • 2017-04-10
      • 2016-02-14
      相关资源
      最近更新 更多