我在代码中发现了一个非常奇怪的错误,只发生在发布版本中。对我来说它看起来像一个Swift bug,但让我知道你的想法。
import Foundation
enum Level : Int {
case
Bad = 0,
Normal = 1,
Good = 2,
Superb = 3
}
struct Attribute : Printable {
var x : Level = .Normal
var y : Level = .Normal
var z : Level = .Normal
var w : Level = .Normal
var description : String {
return "(\(x.rawValue), \(y.rawValue), \(z.rawValue), \(w.rawValue))"
}
func toString() -> String {
return description
}
}
var AccessorBugTestSingleton : AccessorBugTest!
class AccessorBugTest {
let index : Int
var attributes : [Attribute] = []
var todaysAttributes : Attribute {
get {
let r = attributes[index]
println("today: \(r)")
return r
}
}
var initialText : String = ""
// selection for key
var states : [String:Int] = ["x": 0, "y": 0, "z": 0, "w": 0]
var descriptions : [String:Int] = ["a": 0, "b": 0, "c": 0, "d": 0]
init() {
index = 10
for i in 1...31 {
var att = Attribute(x: .Superb, y: .Superb, z: .Superb, w: .Superb)
attributes.append(att)
}
let attribs = todaysAttributes
initialText = "\(attribs)"
println("init: \(attribs), \(self.attributes[index])")
}
}
实例化AccessorBugTest时,应该打印
init: (3, 3, 3, 3), (3, 3, 3, 3)
但在Release版本中打印,
init: (3, 0, 0, 0), (3, 3, 3, 3)
如果我删除未使用的属性states
和descriptions
,那么问题就解决了,不明白为什么。另外,如果我将x
,y
,z
,w
Ints而不是枚举,那么它再次正常工作。
知道发生了什么事吗?
我已将该程序上传到:https://github.com/endavid/AccessorBugTest 它包含一个测试用例,如果你在Release配置中运行它将失败(转到Program - > Scheme - > Edit Scheme,并将Test更改为Release而不是Debug)。
我还下载了Xcode 7.1 beta,在Swift 2.0中尝试过,问题仍然存在:(
答案 0 :(得分:3)
我认为你发现了一个错误。一个非常有趣的错误。
我有一个解决方法:make Attribute是一个类而不是一个struct。它仍然是一个值类,因此开销很低。您必须为它提供一个初始化程序,它执行struct memberwise初始化程序所执行的操作。当你这样做时,你会发现整个问题都消失了。
编辑:我想到了一个更好的解决方法:不要将属性设为类,而是将Level设为@objc
枚举。
编辑: OP报告此错误已在Swift 2.1中修复。