【发布时间】:2012-12-20 18:23:30
【问题描述】:
我正在为 iPad 和 iPod 制作一个 Cookbook 应用程序,并且我的 Cookbook 类中有一组我的 Recipe 类。
@interface Cookbook : NSObject<NSCoding>{
NSMutableArray* recipes;
}
这是在我的食谱课上,在我的食谱课上我有这个:
@interface Recipe : NSObject<NSCoding>{
NSString* name;
NSMutableArray* ingredients; //List of ingredients for the recipe
UIImage* recipePicture;
NSMutableArray* instructions;
unsigned int prepTime;//in seconds
NSDate* dateAdded;
}
(实际上我这里有更多变量,但我不想过多地淹没它)
我的问题基本上在于保存/加载功能。我之前在这里问过一个类似的问题: How can I save an Objective-C object that's not a property list object or is there a better way for this than a property list?
这让我决定最好使用 NSCoding,而且我也已经按照 NSCoding 建议的方式为它实现了一个方法。
我的主要问题是我无法存储和成功检索食谱。
我也无法将目录添加到我的 RecipeList.plist 文件中以存储食谱。
任何帮助将不胜感激,因为这是我无法继续申请的原因。
在我的 Cookbook.m 中,我有:
-(id) initWithCoder:(NSCoder *)aDecoder{
NSLog(@"Init With Coder - Cookbook");
if(self = [super init]){
recipes = [aDecoder decodeObjectForKey:@"recipes"];
}
return self;
}
在我的 Recipe.m 中:
-(id) initWithCoder:(NSCoder *)aDecoder{
if(self = [super init]){
name = [aDecoder decodeObjectForKey:@"name"];
ingredients = [aDecoder decodeObjectForKey:@"ingreds"];
recipePicture = [aDecoder decodeObjectForKey:@"recipePict"];
}
return self;
}
再一次,我有更多的变量,这只是为了简单起见。 此外,这是我尝试获取 RecipeList.plist 的文件路径:
+(NSString*) filePath{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];
path = [path stringByAppendingPathComponent:@"RecipeList.plist"];
NSLog(@"%@",path);
return path;
}
我在 AppDelegate.m 中尝试保存方法:
-(void) save:(NSString *)path cookbook:(Cookbook *)cookbook{
BOOL b = [[NSFileManager defaultManager] fileExistsAtPath:path];
NSLog(@"File exists: %i",b); //1 = exists, 0 = doesn't
NSMutableData* data = [[NSMutableData alloc] init];
if(data){ //If the data object was successfully initialized
NSKeyedArchiver* archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
if(archiver){
//Encode the recipe using the coder method defined in recipe.
[archiver encodeInt:1 forKey:@"Version"];
[archiver encodeObject:cookbook forKey:@"Cookbook"];
[archiver finishEncoding];
[data writeToFile:path atomically:YES];
}
}
}
还有我的加载方法:
-(Cookbook *) loadCookbook:(NSString *)path{
BOOL b = [[NSFileManager defaultManager] fileExistsAtPath:path];
NSLog(@"File exists: %i",b);
Cookbook* ret = nil;
NSData* data = [NSData dataWithContentsOfFile:path];
if(data){
NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
int version = [unarchiver decodeIntForKey:@"Version"];
if(version == 1){
ret = (Cookbook*) [unarchiver decodeObjectForKey:@"Cookbook"];
}
[unarchiver finishDecoding];
}
return ret;
}
我的 Recipe 类也有一个与此非常相似的保存和加载方法。
再次感谢您提供任何帮助,感谢您抽出宝贵时间阅读本文。
编辑:这是 Recipe.m 中的 encodeWithCoder 方法,为简洁起见省略了一些变量:
-(void) encodeWithCoder:(NSCoder *)aCoder{
NSLog(@"Encoding Recipe.");
[aCoder encodeObject:name forKey:@"name"];
[aCoder encodeObject:ingredients forKey:@"ingreds"];
[aCoder encodeObject:recipePicture forKey:@"recipePict"];
[aCoder encodeObject:instructions forKey:@"instructs"];
[aCoder encodeObject:category forKey:@"categ"];
[aCoder encodeObject:dateAdded forKey:@"dateAdd"];
[aCoder encodeInt:prepTime forKey:@"prepTime"];
}
在 Cookbook.m 中:
-(void) encodeWithCoder:(NSCoder *)aCoder{
NSLog(@"Encoding cookbook.");
[aCoder encodeObject:recipes forKey:@"recipes"];
}
【问题讨论】:
-
无论有多少类正在访问它,您都可以从保存按钮中保存它,从打开按钮操作中检索它。如果你想要线程安全,那么你可以选择 atomic,但是 atomic 并不是完全线程安全的。
-
也许题外话,但我会使用核心数据。这将是一个简单的馅饼:)
-
你的
encodeWithCoder:实现中有什么? -
抱歉,代码好长,我还没看完,你是问怎么做还是有一部分代码不起作用?
-
我还想说,我认为仅仅为了使用 Core Data 实现它而拆除你所做的一切是没有意义的。正如一些人可能推断的那样,Core Data 并不是万能的。
标签: objective-c directory filepath save nscoding