Swift - 访问单例字典导致 EXC_BAD_ACCESS

标签 swift dictionary ios8

我有一个管理简单股票投资组合的应用程序。除其他外,它在字典中记录了所需的汇率,如下所示: [ 欧元兑美元=X : 1.267548 ] 这个字典是一个名为 CurrencyRateStore 的单例的字典属性。

更新股票报价时,它会检查更新的汇率并使用以下代码更新字典:

CurrencyRateStore.sharedStore()[symbol] = fetchedRate.doubleValue

调用:

subscript(index: String) -> Double? {
    get {
        return dictionary[index]
    }
    set {
        // FIXME: crashes when getting out of the app (Home button) and then relaunching it
            dictionary[index] = newValue!
            println("CurrencyRateStore - updated rate for \(index) : \(newValue!)")
    }
}

应用首次启动时,运行良好。 但是如果我退出应用程序(使用主页按钮)然后重新启动它,货币汇率会再次更新,但这一次,我在行中得到 EXC_BAD_ACCESS

dictionary[index] = newValue!

截图如下: enter image description here

[编辑] 这是调试导航器中的线程: enter image description here

我尝试更新不带下标的字典,如下所示:

CurrencyRateStore.sharedStore().dictionary[symbol] = fetchedRate.doubleValue

但没有更多的成功。如果我使用函数 updateValue:forKey: 我在 Objective-C 中没有问题。

感谢您的帮助!

[编辑] 这是整个类 CurrencyRateStore:

class CurrencyRateStore {

// MARK: Singleton
class func sharedStore() -> CurrencyRateStore! {
    struct Static {
        static var instance: CurrencyRateStore?
        static var token: dispatch_once_t = 0
    }

    dispatch_once(&Static.token) {
        Static.instance = CurrencyRateStore()
    }

    return Static.instance!
}

// MARK: Properties

/** Dictionary of currency rates used by the portfolio, presented like  [ EURUSD=X : 1.3624 ] */
var dictionary = [String : Double]()

/** Returns a sorted array of all the keys on the currency rates dictionary */
var allKeys: [String] {
var keysArray = Array(dictionary.keys)
    keysArray.sort {$0 < $1}
    return keysArray
}

init() {
    if let currencyRateDictionary: AnyObject = NSKeyedUnarchiver.unarchiveObjectWithFile(currencyRateArchivePath) {
        dictionary = currencyRateDictionary as [String : Double]
    }
}

subscript(index: String) -> Double? {
    get {
        return dictionary[index]
    }
    set {
        // FIXME: crashes when getting out of the app (Home button) and then relaunching it
        // (ApplicationWillEnterForeground triggers updateStocks)
            dictionary[index] = newValue!
            println("CurrencyRateStore - updated rate for \(index) : \(newValue!)")
    }
}


func deleteRateForKey(key: String) {
    dictionary.removeValueForKey(key)
}


/** Removes all currency rates from the Currency rate store */
func deleteAllRates()
{
    dictionary.removeAll()
}


// MARK: Archive items in CurrencyRateStore
var currencyRateArchivePath: String { // Archive path
var documentDirectories: Array = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)

    // Get the only document directory from that list
    let documentDirectory: AnyObject = documentDirectories.first!

    return documentDirectory.stringByAppendingPathComponent("currencyRates.archive")
}

func saveChanges()-> Bool
{
    // return success or failure
    return NSKeyedArchiver.archiveRootObject(dictionary, toFile: currencyRateArchivePath)
}

}

最佳答案

在我看来这像是一个并发问题。 Swift 字典不是线程安全的,从单例中使用它们会导致多个读取器/写入器问题。

编辑:我很确定这是真正的答案,基于给定的源代码/调试转储。为了更正我写的内容,特别是 MUTABLE 字典和数组(以及 NSMutableDictionary 和 NSMutableArray)不是线程安全的,在从多个线程访问的单例中使用它们时会出现问题,这似乎是示例源代码的内容正在执行或启用代码的其他部分执行。

我没有讨论 Swift 集合类线程安全的 Apple 链接,但我很确定这是常识。但是下面关于 Grand Central Dispatch 的教程深入讨论了这个问题以及如何使用 GCD 解决它。

http://www.raywenderlich.com/79149/grand-central-dispatch-tutorial-swift-part-1

关于Swift - 访问单例字典导致 EXC_BAD_ACCESS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26515968/

相关文章:

javascript - 谷歌地图搜索 : Location search is not centered after resize map?

ios - 如何按原样将字符串值传递给 NSString

dependency-injection - Swift 的对象框架宏

swift - 如何在不使用临时变量的情况下在 NSUserDefaults 中写入字典条目?

ios - 从左到右更改导航标题位置

swift - 为什么 dateformatter.date() 默认返回 UTC?

python - 回答完所有问题后无法中断游戏

vb.net - 在 VB.NET 中重载 Equals/GetHashCode 以将对象用作字典键

swift - iOS 8 和 swift : call a function in another class from view controller

双击后 Ios 图表缩小