【问题标题】:Assigning array property is always going to crash EXC_BAD_ACCESS分配数组属性总是会崩溃 EXC_BAD_ACCESS
【发布时间】:2014-09-10 15:57:25
【问题描述】:

我不明白为什么每次使用 Swift 在 Xcode 6 GM 上都会崩溃以下代码。你能帮我理解这个问题吗?

提前谢谢你。

OptionsToSelect.swift

import Foundation

struct OptionToSelect {
    var value : Any
    var desc : String
    var available : Bool
}

SomeClass.swift

import Foundation

class SomeClass {
    var items = Array<OptionToSelect>()
}

ViewController.swift

    override func viewDidLoad() {
        super.viewDidLoad()
        var c = SomeClass()
        c.items = [ /// <------------- __ EXC_BAD_ACCESS here, why?! __
            OptionToSelect(value: 1, desc: "A", available: true),
            OptionToSelect(value: 2, desc: "B", available: true)
        ]
    }

编辑 1 在推特上,我得到的答案是它与Any 相关,确实如此。但是为什么呢?

【问题讨论】:

    标签: ios swift exc-bad-access xcode6 xcode6gm


    【解决方案1】:

    Any 的编译器仍然存在各种问题,因此简短的回答是“Swift 中的错误”。如果value 是一个协议,它也有问题。我怀疑它无法弄清楚如何制作副本;但这是一个猜测。

    但是你应该强烈避免在这里使用Any。你几乎不应该使用Any。在大多数情况下,您需要一个泛型:

    struct OptionToSelect<T> {
      let value : T
      let desc : String
      let available : Bool
    }
    

    (你使用它的方式,let 似乎比这里的var 更合适;你真的需要更改这些值吗?)

    这确实要求整个数组具有相同类型的值:

    var items = [OptionToSelect<Int>]()
    

    但这通常是正确的。如果不是;如果您需要混合值,那么您应该考虑所有值可能符合什么协议。这实际上并不能解决您的问题(Swift 也会在此处的协议上崩溃),但设计会比 Any 好得多。如果你能说的最好的类型是“好吧,它是某种东西”,你会得到很多复杂的(有时是危险的)向下转换代码。每次转身都会与它搏斗。

    要在此处使用协议(或 Any),您可以将 OptionToSelect 设为类(这是最简单的答案),或者将问题隐藏在框中:

    struct OptionToSelect {
      let value : AnyBox
      let desc : String
      let available : Bool
    }
    
    final class AnyBox {
      let value: Any
      init (_ value: Any) { self.value = value }
    }
    
    [
      OptionToSelect(value: AnyBox(1), desc: "A", available: true),
      OptionToSelect(value: AnyBox(2), desc: "B", available: true)
    ]
    

    (协议类型需要相同的技术。)

    【讨论】:

    • 我认为这是错误 #46 的子错误:github.com/practicalswift/swift-compiler-crashes - 一个(比这更糟糕的)解决方法是将OptionToSelect 定义为一个类。
    • 我不知道把OptionToSelect变成一个类是不是很糟糕。这让我感觉很糟糕,但是无论我们如何努力,Swift 似乎都会不断地把你从结构体推到类:D 这个特殊情况似乎正是构建结构体来处理的,并且再一次地结构体有这样或那样的小问题让我们大吃一惊。我似乎遇到了很多。 (我确实希望他们工作;我只是不知道他们是否真的这样做了。)
    • 顺便说一句,#46 在 6.1 中对我来说不会崩溃。
    • 嘿,这就是进步!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-07
    • 1970-01-01
    • 2013-03-24
    • 2010-11-18
    • 2013-01-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多