2013-02-11 46 views
0

我嘗試將創建的自定義對象類添加到nsuserdefaults數組,但它始終保持爲空。我得到的日誌是:向數組添加自定義類對象

「需要注意的是字典和數組在屬性列表也只能包含屬性值」

我的代碼是:

-(void)addProgramWithName:(NSString *)nameOfProgram andWithArrayOfIntervals:(NSMutableArray *)arrayOfIntervals{ 


    Program *tempProgram = [[Program alloc] init]; 
    tempProgram.nameOfProgram = nameOfProgram; 
    tempProgram.arrayOfIntervals = arrayOfIntervals; 

    NSMutableArray *tempArrayOfPrograms = [NSMutableArray arrayWithArray: [[NSUserDefaults standardUserDefaults] arrayForKey: @"arrayOfPrograms"]]; 

    [tempArrayOfPrograms addObject:tempProgram]; 

    [defaults setObject:tempArrayOfPrograms forKey:@"arrayOfPrograms"]; 

    [defaults synchronize]; 

} 

什麼可能的原因是什麼?

回答

1

問題的原因是日誌消息說 - 對於屬性列表,添加到數組(或字典)的任何對象都必須是屬性值(字符串,數字,日期和數組/字典) 。

所以你的情況看來,你已經在值從用戶的默認閱讀,現在你想一些自定義對象添加到您在讀出值。

如果你不打算寫修改後的數組返回給用戶的默認值,這種方法沒有任何問題(儘管它使我對數據結構產生了一定的影響)。

另一方面,如果您需要寫回數據,則只應將屬性值存儲在數組中。對於更復雜的對象,可以通過使用鍵和值將其編碼到字典對象中來完成。

不過,根據您的需求,Core Data可能更適合您的數據。

0

將數組或字典存儲到NSUserDefaults中時,它會壓縮到磁盤上的plist。這意味着您的自定義對象需要轉換爲可以存儲在plist中的格式。有很多方法可以做到這一點,取決於你的對象擁有的數據類型,但這種方法幾乎可以與任何自定義對象一起工作,並且應該非常強大。

由於蘋果公司的精心設計的框架,它很簡單的實現:)

在你Program.h添加<NSCoding>協議。

@interface Program : NSObject <NSCoding> 

然後在您的Program.m請確保您實施以下方法。

#pragma mark - NSCoding 

-(void)encodeWithCoder:(NSCoder *)encoder 
{ 
    // For each of the Program's properties that needs to be stored. 
    [encoder encodeObject:self.property forKey:@"PropertyKey"]; 
} 

-(id)initWithCoder:(NSCoder *)decoder 
{ 
    if (self=[super init]) { 
     self.property = [decoder decodeObjectForKey:@"PropertyKey"]; 
    } 

    return self; 
} 

該協議及其方法允許您的自定義對象在運行中進行編碼和解碼。這很重要,因此我們可以將您的對象轉換爲正確的格式。

接下來我們將在存儲數組之前將其存檔。因此用下面的代碼替換你的代碼:

// Old Line 
// [defaults setObject:tempArrayOfPrograms forKey:@"arrayOfPrograms"]; 

// New Lines 
id archivedObject = [NSKeyedArchiver archivedDataWithRootObject:tempArrayOfPrograms]; 
[defaults setObject:archivedObject forKey:@"arrayOfPrograms"]; 

現在最後一步是確保你在出路上取消存檔。因此,從NSUserDefaults加載陣列的任何地方都要確保將其解壓縮。

// Get the archived array. 
id archivedObject = [[NSUserDefaults standardUserDefaults] objectForKey:@"arrayOfPrograms"]; 

// Unarchive the array. 
NSArray *unarchivedArray = [NSKeyedUnarchiver unarchiveObjectWithData:archivedObject]; 

// Its already a mutable array if you put a mutable array in but just to be safe. 
NSMutableArray *arrayFromDefaults = [NSMutableArray arrayWithArray:unarchivedArray];