1

我已经坚持了大约两个星期。我讨厌张贴被问了很多的东西,但我真的把它们都看完了。

我使用 Ray Wenderlich 的教程在 iPhone 应用程序中保存数据。

http://www.raywenderlich.com/tutorials

这就是我在我的应用程序中进行的设置。我正在保存非常简单的对象。My Card 对象由名称、类型和图像组成。就这样。所以这个教程和我的很接近。这让这更令人沮丧。

问题是,我有一些 NSLog 语句用于加载。我让它显示它用来加载的文件夹以及它加载的对象。现在它正在显示这个。

Loading cards from /Users/zach/Library/Application Support/iPhone Simulator/7.0.3-64/Applications/E3DB01FD-A37E-4A69-840B-43830F2BDE2C/Library/Private Documents
2013-11-04 00:02:50.073 CardMinder[84170:a0b] ()

所以它似乎正在尝试加载它们,但没有任何东西可以加载。这是我保存数据的功能。

- (void)saveData {
    if (_data == nil) return;

    [self createDataPath];

    NSString *dataPath = [_docPath stringByAppendingPathComponent:kDataFile];
    NSMutableData *data = [[NSMutableData alloc] init];
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    [archiver encodeObject:_data forKey:kDataKey];
    [archiver finishEncoding];

    NSLog(@"%@",dataPath);
    NSLog(@"%@",data);

    [data writeToFile:dataPath atomically:YES];

}

这实际上正是该教程中发布的内容。我知道如果你觉得足够慷慨来帮助我,我将不得不发布更多代码,但我不想用无用的东西淹没帖子,所以让我知道,我会在这里发布。

我非常感谢任何可以提供帮助的人,我最近进入了绝望状态,需要帮助。

谢谢

更新

    NSError *error;
    [data writeToFile:dataPath options:NSDataWritingAtomic error:&error];
    NSLog(@"error: %@", error.localizedFailureReason);

这些是 CardData 类的方法。我在这里做名称、类型和布尔值。

- (void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:_name forKey:kNameKey];
    [aCoder encodeObject:_cardType forKey:kTypeKey];
    [aCoder encodeBool:_checkedOut forKey:kOutKey];

}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    NSString *name = [aDecoder decodeObjectForKey:kNameKey];
    NSString *cardType = [aDecoder decodeObjectForKey:kTypeKey];
    BOOL checkedOut = [aDecoder decodeBoolForKey:kOutKey];
    return [self initWithName:name cardType:cardType _Bool:checkedOut];
}

更新 2

我只是在其中添加了一些 NSLog 语句,我发现当我在我的应用程序中按下“保存卡”按钮时,它似乎根本没有执行 saveData 函数。我在 saveData 函数中有大量的日志语句,当我单击 saveCard 按钮时,它不会显示任何这些日志。为什么会这样?

这是我的保存按钮代码。

- (IBAction)saveNewCard:(id)sender
{
    NSString *cardName = self.nameField.text;

    _cardDoc.data.name = cardName;


    CardDoc *newCard = [[CardDoc alloc] initWithName:cardName cardType:cardTypeString _Bool:NO image:chosenIcon];

    [_cardDoc saveData];
    NSLog(@"Card save button pressed!");

    CardViewController *cardViewController = (CardViewController *)[self.navigationController.viewControllers objectAtIndex:self.navigationController.viewControllers.count-2];

    [cardViewController.cards addObject:newCard];
    [self.navigationController popToRootViewControllerAnimated:YES];


}
4

2 回答 2

0

一些东西。

发布您的日志语句的结果,以便我们知道您所看到的。

为了使您的方法起作用,您的 _data 对象需要符合 NSCoding 协议。这意味着您需要将协议声明添加到您的接口,并实现方法 encodeWithCoder 和 initWithCoder。

在这些方法中,您需要保存对象的所有状态数据/将状态加载回对象中。

这些方法最有可能是代码问题的根源。如果您需要帮助,请发布这些方法,并在调试器中遍历它们。

您还可以查看 NSKeyedArchvier 类方法 archivedDataWithRootObject。该方法需要一个对象并一步将其编码为 NSData 对象。方法archiveRootObject:toFile: 更进一步,为您将数据直接写入文件。

NSKeyedUnarchiver 有相应的方法 unarchiveObjectWithData 和 unarchiveObjectWithFile 从数据/文件重新创建你的对象。

于 2013-11-06T02:01:03.417 回答
0

You should use writeToFile:options:error: instead of writeToFile:atomically:; that will give you an error message that should prove helpful. (The equivalent to atomically:YES is the option constant NSDataWritingAtomic.) Make sure you're getting back a return value of YES; if not, the error should be set.

If you're getting a value of NO but the error is not set, it means you're messaging nil. A quirk of Objective-C is that messaging nil is completely valid. If the method is defined to return something, you'll even get a result: 0 or equivalent (NO, nil, etc.)

In this case, you're messaging _cardDoc. There's no return result to detect. This is a bit harder to defensively code around, but [_cardDoc saveData] is actually [nil saveData]. The debugger will just breeze past the line.

Generally, if something absolutely should not be nil, you can use NSAssert:

NSAssert(_cardData, @"_cardData should not be nil");
[_cardData saveData];

But use this sparingly; you'll probably come to usually appreciate this behaviour.

于 2013-11-06T23:54:50.350 回答