7

myWalletという名前のこの可変配列とそのプロパティ宣言があります。

@property (nonatomic, strong) NSMutableArray *myWallet;

この配列は、オブジェクトであるCardsによって埋められています。別のViewControllerからカードの新しいインスタンスを作成するので、デリゲートメソッドを使用して、この作成されたカードを、TableViewControllerである最初のViewControllerに渡すことができます。以下はデリゲートメソッドです

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

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

    [self.tableView reloadData];
}

これまでのところ、Cardの新しいインスタンスを作成できます。作成すると、最初のView Controller(Card Wallet VC)に新しいテーブルセルが表示されます。

私が欲しいのは、ユーザーがアプリの使用を終了したときに、ユーザーが以前に作成したカードの作成されたインスタンスが、アプリの次回の実行時に引き続き表示されることです。そこで、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 プロトコルに準拠する必要があります。つまり、クラスに 2 つのメソッドを追加する必要があります。NSDataNSStringNSArrayNSDictionaryNSNumberNSUserDefaults

- (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 に答える