2012-03-20 2 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

정말 의견이긴하지만 답변으로 게시 해 드리겠습니다.

모델 레이어에 코어 데이터를 사용합니다. 현재와 ​​같이 객체 그래프를 직렬화 할 필요가 없습니다. 오히려 객체 그래프 지속성은 주로 프레임 워크에 의해 처리됩니다. Apple에게는 학습 곡선이 있습니다.이 기술은 "엔트리 레벨 기술"이 아니지만 장기적으로는 훨씬 더 관리하기 쉽습니다.

오브젝트 그래프에서 배열의 직렬화와 관련된 문제는 NSMutableArrayNSCoding 프로토콜을 따릅니다. 다른 문제가 있습니다. 당신은 의미하지

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

배열을 사용하기 전에 다른 위치로 할당/초기화합니다. 나는 일부 테스트 데이터를 저장하는 데 사용하고있는 실제 루프를 표시하기 위해 내 게시물을 업데이트했습니다. 내가 다시 얻을 수있는 것은 'deckName'입니다 (저장하기 전에도!). – wayneh

관련 문제