2012-03-20 6 views
0

私は書いているフラッシュカードアプリのためのマルチレベルのデータを保存する必要があり、私は1)データを管理する方法と2)それを格納する方法を考え出す助けを使用することができます。複数レベルのデータを格納するクラスを作成するにはどうすればよいですか?

データは次のように分類されます a)のカードが2列 Bが含まれています)パックは、文字列「PackName」とカード Cの配列が含まれています)デッキは、文字列「DeckName」とパックの配列が含まれ

今は3つのクラスがあります:カード、パック、デッキ。

//Card.h 
@interface Card : NSObject { 
    NSString  *primaryPhrase; 
    NSString  *secondaryPhrase; 
} 
@property (nonatomic,retain)NSString  *primaryPhrase; 
@property (nonatomic,retain)NSString  *secondaryPhrase; 
@end 


Card.m 
@implementation Card 
@synthesize primaryPhrase; 
@synthesize secondaryPhrase; 
-(id)init{ 
    if(self=[super init]){ 
    } 
    return self; 
} 
@end 

Pack.h 
@interface Pack : NSObject{ 
    NSString  *packName; 
    NSMutableArray *cards; //array of card classes 
    BOOL   isInUse; 
} 
@property (nonatomic,retain)NSMutableArray *cards; 
@property (nonatomic,retain)NSString  *packName; 
@property (nonatomic,assign)BOOL   isInUse; 
@end 

Pack.m 
@implementation Pack 
@synthesize packName; 
@synthesize cards; 
@synthesize isInUse; 
-(id)init{ 
    if(self=[super init]){ 
     self.isInUse=YES; 
    } 
    return self; 
} 
@end 

Deck.h 
@interface Deck : NSObject <NSCoding>{ 
    NSString  *deckName; 
    NSMutableArray *packs; //array of pack classes 
    NSString  *primaryLang; 
    NSString  *secondaryLang; 
} 
@property (nonatomic,retain)NSMutableArray *packs; 
@property (nonatomic,retain)NSString  *deckName; 
@property (nonatomic,retain)NSString  *primaryLang; 
@property (nonatomic,retain)NSString  *secondaryLang; 

- (void) encodeWithCoder:(NSCoder*)encoder; 
- (id) initWithCoder:(NSCoder*)decoder; 
@end 

Deck.m 
#import "Deck.h" 
@implementation Deck 
@synthesize packs; 
@synthesize deckName; 
@synthesize primaryLang; 
@synthesize secondaryLang; 

//Default settings for each new Deck 
-(id)init{ 
    if(self=[super init]){ 
    } 
    return self; 
} 
-(void)encodeWithCoder:(NSCoder*)encoder{ 
    [encoder encodeObject:packs forKey:@"packs"]; 
    [encoder encodeObject:deckName forKey:@"deckName"]; 
    [encoder encodeObject:primaryLang forKey:@"primaryLang"]; 
    [encoder encodeObject:secondaryLang forKey:@"secondaryLang"]; 
} 
-(id)initWithCoder:(NSCoder*)decoder{ 
    if(self=[super init]){ 
     packs=[decoder decodeObjectForKey:@"packs"]; 
     deckName=[decoder decodeObjectForKey:@"deckName"]; 
     primaryLang=[decoder decodeObjectForKey:@"primaryLang"]; 
     secondaryLang=[decoder decodeObjectForKey:@"secondaryLang"]; 
    } 
    return self; 
} 
@end 

その後、私は順番にカードが含まれているデッキを保持するためにNSMutableArrayの「allDecks」を、使用しますが、私も(エラーこの作業を取得することができていないしていないが、「パック名が」常にnullであります):

for(int i=0; i<=2; i++){ 
     Deck *newdeck=[[Deck alloc]init]; 
     [globDat.allDecks addObject:newdeck]; 
    } 
    ((Deck *)[globDat.allDecks objectAtIndex:0])[email protected]"DeckName 0"; 
    ((Deck *)[globDat.allDecks objectAtIndex:1])[email protected]"DeckName 1"; 
    ((Deck *)[globDat.allDecks objectAtIndex:2])[email protected]"DeckName 2"; 
    for(int i=0; i<=2; i++){ 
     Pack *newpack=[[Pack alloc] init]; 
     [((Deck *)[globDat.allDecks objectAtIndex:i]).packs addObject:newpack]; 
    } 
    for(int j=0; j<+2; j++){ 
     ((Pack *)[((Deck *)[globDat.allDecks objectAtIndex:0]).packs objectAtIndex:j])[email protected]"pack name"; 
    } 

    NSLog(@"*** NIL sample pack name=%@",((Pack *)[((Deck *)[globDat.allDecks objectAtIndex:0]).packs objectAtIndex:0]).packName); 
//always returns null 

構造を操作するのはかなり面倒です。 これはこのデータを管理する最善の方法ですか?

さらに、エンコードは埋め込み配列(パックとカード)を保存していないようです。

答えて

1

私はこれを答えとして投稿しますが、実際は意見です。

モデルレイヤにコアデータを使用します。現在のようにオブジェクトグラフをシリアライズする必要はありません。むしろ、オブジェクトグラフの永続性は主にフレームワークによって処理されます。習得の曲線があります - アップルごとに、それは「エントリーレベルの技術」ではありませんが、長期的にははるかに管理しやすくなります。

NSMutableArrayは、NSCodingプロトコルに準拠しています。オブジェクトグラフの配列のシリアル化に関する問題はNSMutableArrayです。他にも問題があります。あなたが意味するものではありませ

packs=[decoder decodeObjectForKey:@"packs"]; 

ん:代わりに

self.packs = [decoder decodeObjectForKey:@"packs"]; 

または

packs = [[decoder decodeObjectForKey:@"packs"] retain]; 

は(私はあなたがARCを使用していないと仮定しています...)

+0

おかげで - 私はコアデータに見ていきます。今、私は残りのコードを稼働させようとしているだけなので、これは今のところうまくいくでしょう。私はARCを使用しているので、「自己」は必須ではありません(他の2つのアプリでそのまま動作します)。 – wayneh

1

正直なところ、私はあなたがしていることを続けていきます。 PackCardが保存されない理由は、それぞれがencodeWithCoder:initWithCoder:のメソッドを実装する必要があるためです。

Card.h

@interface Card : NSObject 

@property (nonatomic,retain)NSString *primaryPhrase; 
@property (nonatomic,retain)NSString *secondaryPhrase; 

@end 

Card.m

@implementation Card 

@synthesize primaryPhrase, secondaryPhrase; 

-(id)init{ 
    if(self=[super init]){ 
    } 
    return self; 
} 

-(void)encodeWithCoder:(NSCoder*)encoder{ 
    [encoder encodeObject:primaryPhrase forKey:@"primaryPhrase"]; 
    [encoder encodeObject:secondaryPhrase forKey:@"secondaryPhrase"]; 
} 

-(id)initWithCoder:(NSCoder*)decoder{ 
    if(self=[super init]){ 
     primaryPhrase=[decoder decodeObjectForKey:@"primaryPhrase"]; 
     secondaryPhrase=[decoder decodeObjectForKey:@"secondaryPhrase"]; 
    } 
    return self; 
} 

@end 

Pack.h

@interface Pack : NSObject 

@property (nonatomic,retain)NSMutableArray *cards; 
@property (nonatomic,retain)NSString  *packName; 
@property (nonatomic,assign)BOOL   isInUse; 

@end 

Pack.m

@implementation Pack 

@synthesize packName, cards, isInUse; 

-(id)init{ 
    if(self=[super init]){ 
     self.isInUse=YES; 
    } 
    return self; 
} 

-(void)encodeWithCoder:(NSCoder*)encoder{ 
    [encoder encodeObject:packName forKey:@"packName"]; 
    [encoder encodeObject:cards forKey:@"cards"]; 
    [encoder encodeObject:[NSNumber numberWithBool:isInUse] forKey:@"isInuse"]; 
} 

-(id)initWithCoder:(NSCoder*)decoder{ 
    if(self=[super init]){ 
     packName=[decoder decodeObjectForKey:@"packName"]; 
     cards=[decoder decodeObjectForKey:@"cards"]; 
     isInUse=[[decoder decodeObjectForKey:@"isInUse"] boolValue]; 
    } 
    return self; 
} 

@end 

デッキ。アドバイスのための時間

@interface Deck : NSObject <NSCoding> 

@property (nonatomic,retain)NSMutableArray *packs; 
@property (nonatomic,retain)NSString  *deckName; 
@property (nonatomic,retain)NSString  *primaryLang; 
@property (nonatomic,retain)NSString  *secondaryLang; 

@end 

Deck.m

#import "Deck.h" 
@implementation Deck 

@synthesize packs, deckName, primaryLang, secondaryLang; 

-(id)init{ 
    if(self=[super init]){ 
    } 
    return self; 
} 

-(void)encodeWithCoder:(NSCoder*)encoder{ 
    [encoder encodeObject:packs forKey:@"packs"]; 
    [encoder encodeObject:deckName forKey:@"deckName"]; 
    [encoder encodeObject:primaryLang forKey:@"primaryLang"]; 
    [encoder encodeObject:secondaryLang forKey:@"secondaryLang"]; 
} 

-(id)initWithCoder:(NSCoder*)decoder{ 
    if(self=[super init]){ 
     packs=[decoder decodeObjectForKey:@"packs"]; 
     deckName=[decoder decodeObjectForKey:@"deckName"]; 
     primaryLang=[decoder decodeObjectForKey:@"primaryLang"]; 
     secondaryLang=[decoder decodeObjectForKey:@"secondaryLang"]; 
    } 
    return self; 
} 
+0

私は各クラスのエンコーディングを使用しようとしましたが、何も変わっていないようです。そのことについては、「パック」を「デッキ」内で使えるようにするのが難しいです。 – wayneh

+0

'allDecks'変数を新しい配列に設定していない可能性があります。 – FreeAsInBeer

+0

私はそれを使用する前に他の場所で配列をalloc/initします。私はいくつかのテストデータを格納するために使用している実際のループを表示するために投稿を更新しました。私が元に戻すことができるのは「deckName」(保存する前でも!)です。 – wayneh

関連する問題