我需要存储我正在编写的闪存卡应用程序的多级数据,我可以使用一些帮助搞清楚1)如何管理数据和2)如何存储它。
数据分解如下: a)卡包含2个字符串 b)Pack包含一个String“PackName”和一组Cards c)Deck包含一个字符串“DeckName”和一个Packs数组
现在我有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”来保存Decks,而Decks又包含Cards,但我甚至无法使其工作(没有错误,但“包名”始终为null):
for(int i=0; i<=2; i++){
Deck *newdeck=[[Deck alloc]init];
[globDat.allDecks addObject:newdeck];
}
((Deck *)[globDat.allDecks objectAtIndex:0]).deckName=@"DeckName 0";
((Deck *)[globDat.allDecks objectAtIndex:1]).deckName=@"DeckName 1";
((Deck *)[globDat.allDecks objectAtIndex:2]).deckName=@"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]).packName=@"pack name";
}
NSLog(@"*** NIL sample pack name=%@",((Pack *)[((Deck *)[globDat.allDecks objectAtIndex:0]).packs objectAtIndex:0]).packName);
//always returns null
使用这个结构非常麻烦。 这是管理这些数据的最佳方式吗?
另外,编码似乎不会保存嵌入式阵列(包和卡)。
答案 0 :(得分:1)
我会发布这个作为答案,虽然这真的是一个意见。
我会将Core Data用于模型层。您不需要像现在一样处理对象图的序列化。相反,对象图持久性主要由框架处理。有一个学习曲线 - 每个Apple,它不是一个“入门级技术” - 但从长远来看它将更易于管理。
对于对象图中序列化序列化的问题,NSMutableArray
符合NSCoding
协议;还有一些问题。而不是:
packs=[decoder decodeObjectForKey:@"packs"];
你不是说:
self.packs = [decoder decodeObjectForKey:@"packs"];
或
packs = [[decoder decodeObjectForKey:@"packs"] retain];
(我假设你没有使用ARC ......)
答案 1 :(得分:1)
老实说,我会继续你做事的方式。 Pack
和Card
未被保存的原因是因为他们每个人都需要实施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
加入deck.h
@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;
}