簡體   English   中英

NSArray中的NSUserDefaults和自定義對象的條件編碼

[英]NSUserDefaults and Conditional Encoding of Custom Objects in an NSArray

我知道有很多關於如何在NSArray或NSMutableArray中歸檔自定義對象並將其保存在NSUserDefaults中的問題。 符合NSCoding協議並保存到NSUserDefaults沒問題,我在很多情況下都使用NSUserDefaults將用戶提交的數據存儲在我的應用程序中-它主要包含代表Person的對象(我們將其稱為NSObject子類“ Person”),在NSMutableArray中存儲了NSObject子類“ Property”的多個對象。 因此,數據結構如下所示:

NSMutableArray "persons":
    Person "aPerson":
        NSMutableArray "properties":
            Property "aProperty"
            Property "anotherProperty"
    Person "anotherPerson:
        ...

最初,存檔和恢復信息沒有問題,因為Person和Property都符合NSCoding協議-但現在發生了一個問題,盡管最近幾天有成千上萬的google請求,但我仍然無法解決;)

一些Property對象包含對其他Person的引用(“參與者”,它們鏈接到相同的屬性,並且包含在NSMutableArray中)。 當我使用NSKeyedArchiver將整個數據存儲到NSUserDefaults時,我使用

[aCoder encodeObject:participants forKey:@"participants"];

在屬性的“ encodeWithCoder”方法中,可以將存儲對其他Person對象的引用的NSMutableArray“參與者”存檔。 但是,當我解碼這些Person對象時,它們是新創建的,並且與其他地方已經存在的Person對象分開。 NSMutableArray“參與者”僅包含引用 ,指向Person對象的弱鏈接,因此應該有條件地對其內容進行編碼 ,就像可以在“ encodeWithCoder”中手動處理其他對象一樣:

[aCoder encodeConditionalObject:anObject forKey:aKey];

當NSMutableArray被解碼時,它應該代表對已經存在的Person對象的引用列表-而不是全新的對象! 測試“ aPerson == [[aDecoder encodingObjectForKey:@“參與者”] objectAtIndex:0]”當前返回NO,盡管它在進行編碼/解碼過程之前返回了YES。

我希望我的解釋是可以理解的,並且您可以幫助我解決我的問題:)簡單來說:如何對NSMutableArray中包含的自定義對象進行條件編碼?

謝謝 !

如果NSMutableArray對它包含的對象使用encodeConditionalObject:forKey:則意味着如果這些對象不是在對象圖中的其他地方無條件地編碼的,則根本不會被編碼。 在這種情況下,這將無濟於事(該數組將為空)。

問題是您無法真正編碼對內存中對象的引用。 對象引用基本上只是指向內存中地址的指針。 下次啟動應用程序並創建相同的對象時(無論是通過取消存檔還是其他方式),幾乎肯定會在內存中具有不同的地址。 取消存檔程序無法“神奇地”知道哪個現有對象與其已存檔的引用相對應,因為當您退出應用程序時,內存地址(對象的“身份”)會失去所有含義。

您必須使用其他方法來標識您的對象,例如數據庫行ID,字典鍵等,並手動建立已歸檔鍵和與該鍵對應的現有對象的連接。

我也有這個問題。 我的對象具有與其他對象的一系列弱鏈接。 我知道鏈接到的所有對象都會被編碼,因此我只想確保可以重建鏈接。

使用單個弱鏈接可以使用:

aCoder.encodeConditionalObject(thing, forKey: "Thing")

...並且如果該商品已從其他位置進行編碼,則將使用對該編碼商品的引用。

但是,如果您有一個充滿“條件”項的數組,而該數組需要無條件編碼,該怎么辦?

我最后包裝了要鏈接的項目。

class thingLink: NSObject, NSCoding
{
    weak var thing: Thing?

    init(_ thing: Thing) {
        self.thing = thing
    }

    required init?(coder aDecoder: NSCoder) {
        thing = aDecoder.decodeObject(forKey: "Thing") as? Thing
    }

    func encode(with aCoder: NSCoder) {
        // We encode these conditionally as they must be used elsewhere
        aCoder.encodeConditionalObject(thing, forKey: "Thing")
    }
}

...然后將它們存儲在我通常編碼的數組中。

aCoder.encode(things, forKey: "Things")

如果我移到數據庫來存儲內容,我認為這也將有所幫助,因為我需要一個單獨的表來存儲鏈接並保持優先級等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM