向数组添加自定义类对象

问题描述:

我尝试将创建的自定义对象类添加到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]; 

} 

什么可能的原因是什么?

问题的原因是日志消息说 - 对于属性列表,添加到数组(或字典)的任何对象都必须是属性值(字符串,数字,日期和数组/字典) 。

所以你的情况看来,你已经在值从用户的默认阅读,现在你想一些自定义对象添加到您在读出值。

如果你不打算写修改后的数组返回给用户的默认值,这种方法没有任何问题(尽管它使我对数据结构产生了一定的影响)。

另一方面,如果您需要写回数据,则只应将属性值存储在数组中。对于更复杂的对象,可以通过使用键和值将其编码到字典对象中来完成。

不过,根据您的需求,Core Data可能更适合您的数据。

将数组或字典存储到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];