我有一個簡單的類,用於跟蹤字典中各種應用程序功能的使用情況。當App被髮送到後臺時,字典被保存到NSUserDefaults,並且當App第一次啓動時從NSUserDefaults讀取。在向字典添加一些使用密鑰後,發送到後臺,然後重新打開並寫入它,我得到一個錯誤的訪問錯誤。Crash訪問Singleton中的Swift字典值
該字典應該是可寫的,我從NSUserDefaults讀取時重新分配一個新的字典,並將保存的使用密鑰/對象添加到它。在我編寫時,鍵和對象都是有效的(對於鍵,對象是[String:String]),就像我的類對象和字典本身一樣。我確信我在這裏做了一些愚蠢的事情,但無法弄清楚什麼。
以下是帶有重要方法的類,包括Singleton實現。
enum UsageType: Int {case ActivationHelp = 0, FullAccessHelp, ContactUs, PrivacyLink}
func usageTypeKey(usage :UsageType) -> String {
switch usage {
case .ActivationHelp:
return "Activation"
case .FullAccessHelp:
return "FullAccess"
case .ContactUs:
return "ContactUs"
case .PrivacyLink:
return "PrivacyLink"
}
}
class UsageMgr {
var usageDb = ["default key": "default value"]
private let formatter : NSDateFormatter?
//--------------------------------- Init -----------------------------------
init() {
formatter = NSDateFormatter()
formatter?.dateStyle = .MediumStyle
formatter?.timeStyle = .MediumStyle
self.read()
}
//--------------------------------- Singletons -----------------------------------
class var sharedInstance : UsageMgr {
struct Singleton {
static let instance = UsageMgr()
}
let existingInstance = Singleton.instance
return existingInstance
}
class func markUsed(usage : UsageType) {
let mgr = UsageMgr.sharedInstance
mgr.markUsed(usage)
}
//--------------------------------- Accessors ------------------------------
func markUsed(usage : UsageType) {
let typeKey = usageTypeKey(usage)
let now = NSDate()
let dateString = self.formatter?.stringFromDate(now)
if let date = dateString {
self.usageDb[typeKey] = date
}
}
func saveDefaults() {
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(usageDb, forKey: "Usage2")
defaults.synchronize()
}
func read() {
// *** Have to reallocate every time we are re-opened, not sure why
// Appears usageDb is being freed by ARC
self.usageDb = [String: String]()
let defaults = NSUserDefaults.standardUserDefaults()
let defaultsUsageOpt = defaults.objectForKey("Usage2") as [String : String]?
if let usageList = defaultsUsageOpt {
for (key, dateString) in usageList {
usageDb[key] = dateString
}
}
}
}
的碰撞的方法寫入到詞典時,會發生markUsed就行
self.usageDb[typeKey] = date
確切的錯誤是EXC_BAD_ACCESS在我的代碼行(從類方法調用訪問方法),但線程方法堆棧的底部在「swift_unknownRelease」處結束,這意味着我的字典中的鍵/對象以某種方式被釋放。但是我創建了對我的AppDelegate中Singleton和字典的引用,並且崩潰仍然發生。
調試器告訴我一切都在崩潰點
(lldb) po usageDb
{[0] = (key = "Activation", value = "Mar 25, 2015, 2:35:49 PM")
[1] = (key = "PrivacyLink", value = "Mar 29, 2015, 8:50:16 PM")
[2] = (key = "ContactUs", value = "Apr 3, 2015, 12:24:39 PM")
[3] = (key = "FullAccess", value = "Apr 3, 2015, 12:24:49 PM")
}
(lldb) po typeKey
"FullAccess"
(lldb) po date
"Apr 3, 2015, 12:24:59 PM"
(lldb) po self
0x0000000178039180
{
usageDb = {
[0] = (key = "Activation", value = "Mar 25, 2015, 2:35:49 PM")
[1] = (key = "PrivacyLink", value = "Mar 29, 2015, 8:50:16 PM")
[2] = (key = "ContactUs", value = "Apr 3, 2015, 12:24:39 PM")
[3] = (key = "FullAccess", value = "Apr 3, 2015, 12:24:49 PM")
}
formatter = Some {
Some = 0x0000000178056da0 {
Foundation.NSFormatter = {
ObjectiveC.NSObject = {}
}
}
}
}
這是Xcode的6.2潔淨,所以它的雨燕1.1。我已經考慮過一個線程問題,比如多個讀者/作者,但是在我的代碼正在做什麼時沒有意義,並且我寫了一個多讀/單編寫器實現,這沒有幫助。字典似乎在我的應用程序的其他地方工作正常,我不知道我在這裏做什麼是不同/不好。
確切的崩潰是「EXC_BAD_ACCESS」 – 2015-04-03 19:55:30
代碼的某些部分未定義,例如類UsageType。我改變了一點,運行它,它的工作原理。您想添加如何使用UsageMgr嗎?同樣在markUsed()中,你確定typeKey不是零嗎? – TimeString 2015-04-03 20:12:55
TimeString,感謝您指出監督,添加UsageType/UsageTypeKey()定義。當用戶使用/看到功能/幫助屏幕時,會調用UsageMgr.markUsed()以記錄使用情況。第一次調用自動進入Singleton類並調用UsageMgr.read()從磁盤讀取先前的版本。 UsageMgr.save()從我的AppDelegate.applicationDidEnterBackground中調用。調試程序指出typeKey是在崩潰點處的字符串「FullAccess」。 – 2015-04-03 21:58:53