Fré*_*dda 11 dictionary swift ios8
我有一个管理简单的股票投资组合的应用程序。除其他事项外,它在字典中保留所需汇率的记录,例如:[EURUSD = X:1.267548]此自由裁量权是单身人士的Dictionary属性,称为CurrencyRateStore。
更新股票报价时,它将检查更新的汇率并使用以下代码更新字典:
CurrencyRateStore.sharedStore()[symbol] = fetchedRate.doubleValue
Run Code Online (Sandbox Code Playgroud)
那叫:
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!)")
}
}
Run Code Online (Sandbox Code Playgroud)
首次启动应用程序时,它可以正常运行。但是,如果我退出该应用程序(使用“主页”按钮),然后重新启动,则汇率会再次更新,但是这次,我在该行得到了EXC_BAD_ACCESS
dictionary[index] = newValue!
Run Code Online (Sandbox Code Playgroud)
这是屏幕截图:

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

我尝试不带下标来更新字典,如下所示:
CurrencyRateStore.sharedStore().dictionary[symbol] = fetchedRate.doubleValue
Run Code Online (Sandbox Code Playgroud)
但没有更多的成功。如果我使用函数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)
}
}
Run Code Online (Sandbox Code Playgroud)
Saf*_*ive 11
在我看来,这似乎是一个并发问题。Swift字典不是线程安全的,并且单例使用它们可能会导致多个读取器/写入器问题。
编辑:我很确定这是真正的答案,基于给定的源/调试转储。要纠正我写的内容,特别是MUTABLE字典和数组(以及NSMutableDictionary和NSMutableArray)不是线程安全的,并且在从多个线程访问的Singleton中使用它们时会出现问题,这似乎是示例源代码正在执行或使代码的其他部分能够执行。
我没有讨论Swift集合类线程安全的Apple链接,但是我很确定常识。但是下面有关Grand Central Dispatch的教程深入讨论了该问题以及如何使用GCD解决该问题。
http://www.raywenderlich.com/79149/grand-central-dispatch-tutorial-swift-part-1
| 归档时间: |
|
| 查看次数: |
2880 次 |
| 最近记录: |