7

我有这个名为 myWallet 的可变数组及其属性声明:

@property (nonatomic, strong) NSMutableArray *myWallet;

这个数组被 Cards 填充,它是一个对象。我从另一个视图控制器创建了一个卡片的新实例,因此我使用委托方法能够在我的初始视图控制器(表视图控制器)上传递这个创建的卡片。下面是委托方法

- (void)addCardViewController:(AddCardViewController *)sender didCreateCard:(Card *)newCard
{
    // insert a new card

    self.myCard = newCard;
    [self.myWallet addObject:self.myCard];

    [self.tableView reloadData];
}

到目前为止,我可以创建 Card 的新实例,当我这样做时,一个新的表格单元格会出现在我的初始视图控制器(Card Wallet VC)中。

我想要的是当用户完成使用应用程序时,他/她之前创建的 Card 的创建实例仍然出现在应用程序的下一次运行时。所以我使用 NSUserDefaults 来做到这一点。下面的方法是我使用 NSUserDefaults 保存的方法。

- (void)saveMyWallet
{

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    [defaults setObject:self.myWallet forKey:@"myWalletArray"];

    [defaults synchronize];
    NSLog(@"I am saved");
}

我在 didSelectRowAtIndexPath 中调用此方法。当我运行该应用程序,然后创建一个卡片的新实例时,单击表格单元格,这将出现在我的日志中。

2012-05-04 14:51:00.900 CardWallet[24998:f803] *** -[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value '("<Card: 0x6aa02f0>")' of class '__NSArrayM'.  
Note that dictionaries and arrays in property lists must also contain only property values.

这可能是什么原因?你能建议我如何去做吗?

提前致谢。

4

3 回答 3

4
@implementation Card

- (void)encodeWithCoder:(NSCoder *)enCoder 
{
    [super encodeWithCoder:enCoder];
    [enCoder encodeObject:self.name forKey:@"CardName"];
    [enCoder encodeInt:self.pin forKey:@"CardPin"];
    [enCoder encodeDouble:self.points forKey:@"CardPoints"];
}

- (id)initWithCoder:(NSCoder *)aDecoder 
{
   if(self = [super initWithCoder:aDecoder]) 
   {
       self.name = [aDecoder decodeObjectForKey:@"CardName"];
       self.pin = [aDecoder decodeIntForKey:@"CardPin"];
       self.points = [aDecoder decodeDoubleForKey:@"CardPoints"];      
   }
   return self;
}

@end

假设名称是 NSString 类型,pin 是 NSInteger 类型,Points 是 Double 类型,您可以直接在项目中使用上述代码。

于 2012-05-04T07:41:04.880 回答
4

您的 Card 类还必须符合NSCoding 协议,因为您只能存储NSDataNSStringNSArray和with 。这意味着,您需要向您的类添加两个方法:NSDictionaryNSNumberNSUserDefaults

- (void)encodeWithCoder:(NSCoder *)enCoder {
    [super encodeWithCoder:enCoder];

    [enCoder encodeObject:instanceVariable forKey:INSTANCEVARIABLE_KEY];

    // Similarly for the other instance variables.
    ....
}

- (id)initWithCoder:(NSCoder *)aDecoder {

   if(self = [super initWithCoder:aDecoder]) {
       self.instanceVariable = [aDecoder decodeObjectForKey:INSTANCEVARIABLE_KEY];

       // similarly for other instance variables
       ....
   }

   return self;
}

然后在将其存储到 NSUserDefaults 之前创建一个 NSData NSKeyedArchiver。像这样:

 NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
 NSData *yourArrayAsData = [NSKeyedArchiver archivedDataWithRootObject:yourArray];
 [ud setObject:sharesAsData forKey:kA_KEY_FOR_USERDEFAULTS];
于 2012-05-04T06:58:51.440 回答
0

如果数组self.myWallet包含不是属性列表对象的对象,则需要NSData在保存之前自行对其进行编码,并在加载时进行解码。

查看该问题的答案。

于 2012-05-04T06:59:00.863 回答