Iphone 向数组添加自定义类对象

Iphone 向数组添加自定义类对象,iphone,xcode,Iphone,Xcode,我尝试将我创建的自定义对象类添加到nsuserdefaults数组中,但它始终保持为空。我得到的日志是: “请注意,属性列表中的词典和数组也必须仅包含属性值” 我的代码是: -(void)addProgramWithName:(NSString *)nameOfProgram andWithArrayOfIntervals:(NSMutableArray *)arrayOfIntervals{ Program *tempProgram = [[Program alloc] init]

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

}

原因可能是什么?

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

因此,在您的例子中,您似乎已经从用户默认值中读入了值,现在您希望将一些自定义对象添加到已读入的值中

如果您不打算将修改后的数组写回用户默认值,那么这种方法没有错(尽管我觉得它是一种处理数据结构的非常努力的方法)

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


根据您的需要,核心数据可能更适合您的数据。

当您将数组或字典存储到NSUserDefaults中时,它会压缩为磁盘上的plist。这意味着您的自定义对象需要转换为可以存储在plist中的格式。有很多方法可以做到这一点,这取决于您的对象所持有的数据类型,但是这种方法将适用于几乎任何自定义对象,并且应该非常健壮

多亏了苹果精心设计的框架,实现起来非常简单:)

程序.h
中添加
协议

@interface Program : NSObject <NSCoding>
此协议及其方法允许对自定义对象进行动态编码和解码。这一点很重要,这样我们可以将您的对象转换为正确的格式

接下来,我们将在存储阵列之前对其进行归档。因此,用以下代码替换您的代码:

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

// New Lines
id archivedObject = [NSKeyedArchiver archivedDataWithRootObject:tempArrayOfPrograms];
[defaults setObject:archivedObject forKey:@"arrayOfPrograms"];
现在,最后一步是确保您在退出的过程中没有陷入困境。因此,无论从哪里加载数组,请确保取消归档

// 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];
// 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];