2015-09-26 33 views
0

我在Xcode 7(Swift 2)上運行應用程序時出現了一個非常奇怪的錯誤,該應用程序委託中顯示運行錯誤消息的「線程1:信號SIGABRT」我的應用程序類。不過,實際上,我已經在App Delegate類中多次出現了此「線程1:信號SIGABRT」運行錯誤消息,主要是在刪除代碼中的插座引用並忘記將其從故事板中刪除時。但是,這肯定是我第一次試圖使命令時,得到了同樣的錯誤:應用程序嘗試向NSUserDefaults添加元素時委託出現奇怪的錯誤

let wasteGain = WastesGainsClass(value: enteredMoney, originOrCat: segControlArray[segControl.selectedSegmentIndex], specification: plusEspecTField.text!, date: dateArray, mode: "gain") 

gains.append(wasteGain) 

NSUserDefaults.standardUserDefaults().setObject(gains, forKey: "gains") 

什麼情況是,如果我只是註釋行NSUserDefaults.standardUserDefaults().setObject(gains, forKey: "gains")應用程序不會崩潰!所以這個錯誤可能就在那一行。

如果有人能幫助我,我非常感謝你。

PS:WastesGainsClass格式是這樣的:

class WastesGainsClass { 

    var value:Int = 0 
    var origin:String 
    var specification:String 
    var date:[String] 
    var mode:String 
    var rowMode:Int = 0 

    init(value:Int, originOrCat:String, specification:String, date:[String], mode:String) { 

     self.value = value 
     self.origin = originOrCat 
     self.specification = specification 
     self.date = date 
     self.mode = mode 

    } 

} 
+0

唯一的財產清單符合類型('NSNumber','NSString','NSDate','NSData')而集合類型'NSArray'和'NSDictionary'可以用'NSUserDefaults'保存。集合類型也必須包含屬性列表兼容類型。對於自定義類,您的類必須符合'NSCoding'以使用'NSKeyedArchiver/Unarchiver'存檔。 – vadian

+0

@vadian您應該添加該答案作爲答案;這正是問題/解決方案所在。 –

+0

[嘗試將非屬性列表對象設置爲NSUserDefaults]的可能重複(http://stackoverflow.com/questions/19720611/attempt-to-set-a-non-property-list-object-as- an-nsuserdefaults) – Glenn

回答

1

documentation

的類NSUserDefaults的提供用於訪問 常見類型如浮標方便的方法,雙打,整數,布爾值,和URL。 A 默認對象必須是一個屬性列表,也就是,一個實例(或針對集合的一個實例組合)(實例的組合):NSData,NSString,NSNumber,NSDate,NSArray或NSDictionary。如果要存儲任何其他類型的對象,則通常應將其存檔以創建一個NSData實例。

在斯威夫特你也可以使用:

  • IntUIntDoubleFloatBool類型,因爲它們會自動橋接NSNumber;
  • String橋接到NSString
  • [AnyObject],因爲它被搭橋,以NSArray;
  • [NSObject: AnyObject]因爲它橋接到NSDictionary

當然,數組元素和字典值的類型必須是以上類型之一。字典密鑰類型必須是NSString(或橋接String)。

存儲的其他類的情況下,你有兩個選擇:

  1. 您的自定義類必須是NSObject子類,符合 NSCoding協議,然後你可以用NSKeyedArchiver.archivedDataWithRootObject()歸檔這個類的對象NSData它從NSUserDefaults和取消歸檔保存到NSUserDefaults,並在以後檢索與NSKeyedUnarchiver.unarchiveObjectWithData()

    import Foundation 
    
    class WastesGainsClass: NSObject, NSCoding { 
        var value: Int 
    
        init(value: Int) { 
         self.value = value 
        } 
    
        required init(coder aDecoder: NSCoder) { 
         value = aDecoder.decodeObjectForKey("value") as! Int 
        } 
    
        func encodeWithCoder(aCoder: NSCoder) { 
         aCoder.encodeObject(value, forKey: "value") 
        } 
    } 
    
    var gains = [WastesGainsClass(value: 1), WastesGainsClass(value: 2)] 
    NSUserDefaults.standardUserDefaults().setObject(gains.map { NSKeyedArchiver.archivedDataWithRootObject($0) }, forKey: "gains") 
    
    if let gainsData = NSUserDefaults.standardUserDefaults().objectForKey("gains") as? [NSData] { 
        gains = gainsData.map { NSKeyedUnarchiver.unarchiveObjectWithData($0) as! WastesGainsClass } 
    } 
    
  2. 您可以保存您的自定義對象屬性字典和存儲NSUserDefaults該 詞典:

    import Foundation 
    
    class WastesGainsClass { 
        var value: Int 
    
        init(value: Int) { 
         self.value = value 
        } 
    } 
    
    extension WastesGainsClass { 
        convenience init(dict: [NSObject: AnyObject]) { 
         self.init(value: dict["value"] as? Int ?? 0) 
        } 
    
        func toDict() -> [NSObject: AnyObject] { 
         var d = [NSObject: AnyObject]() 
         d["value"] = value 
         return d 
        } 
    } 
    
    var gains = [WastesGainsClass(value: 1), WastesGainsClass(value: 2)] 
    
    NSUserDefaults.standardUserDefaults().setObject(gains.map { $0.toDict() }, forKey: "gains") 
    
    if let dicts = NSUserDefaults.standardUserDefaults().objectForKey("gains") as? [[NSObject: AnyObject]] { 
        gains = dicts.map { WastesGainsClass(dict: $0) } 
    } 
    
1

NSUserDefaults遺憾的是不能接受任意對象,只可在屬性列表進行編碼的對象。請參閱Apple's reference guide for Property Lists以瞭解可以存儲哪些對象。

如果您需要保存幾WastesGainsClass對象,你不妨寫一個返回Dictionary編碼它們的屬性列表,表示的性能的方法,並接受這樣的Dictionary恢復對象的初始化。

但是,如果您確實需要保存這樣的多個自定義對象,則可能根本不想使用NSUserDefaults。考慮一個基於文檔的應用程序,並查看NSCoding

0

您發佈的代碼嘗試將自定義對象數組保存到NSUserDefaults。你不能那樣做。實施NSCoding方法沒有幫助。您只能在NSUserDefaults中存儲NSArray,NSDictionary,NSString,NSData,NSNumber和NSDate等內容。

您需要將對象轉換爲NSData(就像您在某些代碼中一樣)並將該NSData存儲在NSUserDefaults中。如果需要,您甚至可以存儲NSData的NSArray。

看到此信息:Attempt to set a non-property-list object as an NSUserDefaults

+0

'當您使用NSKeyedArchiver.archivedDataWithRootObject()將自定義類的實例歸檔爲「NSData」時使用NSCoding協議,稍後使用NSKeyedUnarchiver.unarchiveObjectWithData檢索它。 – mixel

+0

@mixel:請重新閱讀(並刪除您的投票):答案是相關的,而帖子實際上是來自推薦帖子的重複。好吧,我也提到NSCodings,因爲它在其他答案中提到過(而不是在這裏)。但是尼古拉斯有完全相同的問題和錯誤 – Glenn

相關問題