附加到数组类属性时的EXC_BAD_ACCESS

时间:2017-12-27 10:12:39

标签: arrays swift cordova

我刚开始使用swift并且已经转换了一些ios firebase cordova插件,但遇到了一些我对阵列不太了解的情况。我有两个代码片段,一个有效,另一个无代码。

作品

var admobTestDevices: [Any] = []
var randomString: String = "abc123"

@objc(FirebasePlugin)
class FirebasePlugin : CDVPlugin {
  func something() {
    admobTestDevices.append(randomString)
  }
}

不能工作

@objc(FirebasePlugin)
class FirebasePlugin : CDVPlugin {
  var admobTestDevices: [Any] = []
  var randomString: String = "abc123"

  func something() {
    admobTestDevices.append(randomString)
  }
}

不起作用的那个会产生Thread 1: EXC_BAD_ACCESS (code=1, address=0x8)错误。为什么一个工作而另一个不工作?将可变数组作为类属性的正确方法是什么?

2 个答案:

答案 0 :(得分:0)

我不是想在我的CDVPlugin子类上直接存储数组,但是我存储了一个Queue<T>作为顶级的结构Array<T>成员,它导致了你看到的同样的错误。我的解决方案是用pluginInitialize方法重复数组初始化:

struct Queue<T>: ExpressibleByArrayLiteral {
    public private(set) var elements: Array<T>

    public init() {
        self.elements = []
    }

    public init(arrayLiteral elements: T...) {
        self.elements = elements
    }

    // ...other members...
}

@objc(MyPlugin) class MyPlugin: CDVPlugin {
    var requestQueue: Queue<DownloadRequest> = []

    override func pluginInitialize() {
        requestQueue = Queue<DownloadRequest>()
    }

    // ...other members...
}

这种代码通常不是必需的进入自定义初始化程序,但是the CDVPlugin source警告不要对初始化程序进行子类化,而是使用pluginInitialize代替。科尔多瓦显然在这里做了一些与众不同的事情,所以我倾向于相信他们。

答案 1 :(得分:0)

出于某些原因,在某些情况下,集合在子类中变得不可变。

您可以通过以下两种方法解决此问题:

1。覆盖init()初始化数组,然后调用super.init

class FirebasePlugin : CDVPlugin {

    var admobTestDevices: [Any] = []
    var randomString: String = "abc123"

    override init() {
        admobTestDevices = [Any]()
        super.init()
    }

  func something() {
    admobTestDevices.append(randomString)
  }
}

2。使用lazy修饰符,以便在首次使用数组时对其进行初始化。

class FirebasePlugin : CDVPlugin {

    lazy var admobTestDevices: [Any] = []
    var randomString: String = "abc123"

    func something() {
        admobTestDevices.append(randomString)
    }
}