我在代码中发现了一个非常奇怪的错误,该错误仅在Release版本中发生。在我看来,这似乎是Swift的错误,但请告诉我您的想法。
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,wint类型而不是枚举,然后重新正常工作。
states
descriptions
x
y
z
w
知道发生了什么吗?
我已将该程序上传到:https : //github.com/endavid/AccessorBugTest 它包含一个测试用例,如果您在Release配置中运行它,该测试用例将失败(转到Program-> Scheme-> Edit Scheme,然后将Test更改为发布而不是调试)。
我还下载了Xcode 7.1 beta,在Swift 2.0中进行了尝试,但问题仍然存在:(
我认为您已找到一个错误。一个非常有趣的错误。
我有一个解决方法:将Attribute设为类而不是struct。它仍将是一个值类,因此开销将很低。您将不得不给它一个初始化器,该初始化器执行struct逐成员初始化器的作用。执行此操作后,您会发现整个问题都消失了。
编辑: 我想到了一个更好的解决方法:而不是使Attribute为一个类,而是使Level为@objc枚举。
@objc
编辑: OP报告此错误已在Swift 2.1中修复。