1

我正在为 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;
}

(实际上我这里有更多变量,但我不想过多地淹没它)

我的问题基本上在于保存/加载功能。我之前在这里问过一个类似的问题: 如何保存不是属性列表对象的 Objective-C 对象,或者有比属性列表更好的方法吗?

这让我决定最好使用 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;
}

在我的食谱中:

-(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"];
}
4

1 回答 1

0

我已经“几乎”复制粘贴了您的代码,经过一些小的调整后,我已经启动并运行了它。

在食谱中,我添加了:

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

- (void)addRecipe:(Recipe *)recipe {
    [recipes addObject:recipe];
}

你可能已经有了这些?我假设您正在某处实例化数组?

然后使用这个测试例程,完美地创建、使用和保存食谱:

NSString *path = [self filePath];
Cookbook *cookbook = [self loadCookbook:path];

if (cookbook) {
    NSLog(@"Loaded cookbook: %@", cookbook);
}
else {
    cookbook = [[Cookbook alloc] init];
}

Recipe *recipe = [[Recipe alloc] init];
recipe->name = @"The name";
[cookbook addRecipe:recipe];

[self save:path cookbook:cookbook];
NSLog(@"Saved cookbook: %@", cookbook);

仅供参考:为简洁起见,我将配方的实例变量设为@public;希望您正在使用访问器(@property)。

您使用自动或手动引用计数?

于 2012-12-21T09:19:28.957 回答