简体   繁体   English

数据加载但无法保存iPhone应用程序

[英]Data loads but won't save iPhone app

I've been stuck on this for approximately two weeks. 我已经坚持了大约两个星期。 I hate posting things that have been asked a lot but I really have gone through them all. 我讨厌发布很多被问到的东西,但我确实经历了所有这些事情。

I used Ray Wenderlich's tutorial for saving data in an iPhone app. 我使用Ray Wenderlich的教程将数据保存在iPhone应用程序中。

http://www.raywenderlich.com/tutorials http://www.raywenderlich.com/tutorials

So that is the setup I have going on in my app. 这就是我在应用程序中进行的设置。 I'm saving very simple objects. 我正在保存非常简单的对象。 My Card object consists of a name, type, and image. 我的名片对象由名称,类型和图像组成。 That's all. 就这样。 So the tutorial is quite close to mine. 因此,本教程与我的教程非常接近。 Which is making this more frustrating. 这使这更加令人沮丧。

The thing is, I have some NSLog statements in there for loading. 问题是,我那里有一些NSLog语句要加载。 I have it displaying the folder it's using to load and what objects it does load. 我让它显示用于加载的文件夹以及它加载的对象。 Right now it is displaying this. 现在它正在显示此。

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] ()

So it seems to be trying to load them, but there's nothing there to load. 因此,它似乎正在尝试加载它们,但是没有任何要加载的内容。 Here is my function to save data. 这是我保存数据的功能。

- (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];

}

Which is really just what's posted in that tutorial. 这实际上就是该教程中发布的内容。 I know if you feel generous enough to help me out i'll have to post some more code but I don't want to flood the post with useless stuff so just let me know and i'll get it out here. 我知道如果您足够慷慨地帮助我,我将不得不发布更多代码,但我不想在无用的内容中充斥这篇文章,所以请告诉我,我会在这里解决。

I really appreciate anyone that can help, I have recently entered the desperation state and need help. 我真的很感谢任何可以提供帮助的人,我最近陷入了绝望的状态,需要帮助。

Thanks 谢谢

UPDATE UPDATE

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

These are the methods for the CardData class. 这些是CardData类的方法。 I'm doing the name, type, and a bool here. 我在这里输入名称,类型和名称。

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

UPDATE 2 更新2

I just put some more NSLog statements in and I found out that when I press the "Save card" button in my app, it doesn't seem to execute the saveData function at all. 我只是添加了一些NSLog语句,发现当我在应用程序中按“保存卡”按钮时,它似乎根本不执行saveData函数。 I have log statements galore in that saveData function and when I click the saveCard button it doesn't show any of those logs. 我在该saveData函数中有大量的日志语句,当我单击saveCard按钮时,它不显示任何这些日志。 Why would that be happening? 为什么会这样呢?

This is my saveButton code. 这是我的saveButton代码。

- (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];


}

A few things. 一些东西。

Post the results of your log statements so we know what you are seeing. 发布您的日志语句的结果,以便我们了解您所看到的。

In order for your approach to work, your _data object needs to conform to the NSCoding protocol. 为了使您的方法有效,您的_data对象需要符合NSCoding协议。 That means you need to add the protocol declaration to your interface, and implement the methods encodeWithCoder and initWithCoder. 这意味着您需要将协议声明添加到您的接口,并实现方法encodeWithCoder和initWithCoder。

In those methods you need to save all the state data for your object / load the state back into your object. 在这些方法中,您需要保存对象的所有状态数据/将状态重新加载到对象中。

Those methods are the most likely source of problems with your code. 这些方法很可能是您的代码问题的根源。 Post those methods if you need help with them, and walk though them in the debugger. 如果您需要有关这些方法的帮助,请发布这些方法,然后在调试器中遍历它们。

You might also look at the NSKeyedArchvier class method archivedDataWithRootObject. 您可能还会查看NSKeyedArchvier类方法archivedDataWithRootObject。 That method takes an object and encodes it into an NSData object in one step. 该方法只需一个步骤即可将一个对象编码为一个NSData对象。 The method archiveRootObject:toFile: take it a step further, and writes the data directly to a file for you. 方法archiveRootObject:toFile:更进一步,并将数据直接写到文件中。

NSKeyedUnarchiver has the corresponding methods unarchiveObjectWithData and unarchiveObjectWithFile to recreate your object from data/a file. NSKeyedUnarchiver具有相应的方法unarchiveObjectWithData和unarchiveObjectWithFile从数据/文件重新创建对象。

You should use writeToFile:options:error: instead of writeToFile:atomically: ; 您应该使用writeToFile:options:error:而不是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 ; (等效于NSDataWritingAtomic atomically:YES是选项常量NSDataWritingAtomic 。)确保您返回的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 . 如果您获得的值为NO但未设置错误,则表示您正在传递nil A quirk of Objective-C is that messaging nil is completely valid. Objective-C的一个怪癖是, nil消息传递是完全有效的。 If the method is defined to return something, you'll even get a result: 0 or equivalent ( NO , nil , etc.) 如果将方法定义为返回值,您甚至会得到结果: 0或等效值( NOnil等)

In this case, you're messaging _cardDoc . 在这种情况下,您正在传递_cardDoc There's no return result to detect. 没有返回结果要检测。 This is a bit harder to defensively code around, but [_cardDoc saveData] is actually [nil saveData] . 进行防御性编码比较困难,但是[_cardDoc saveData]实际上是[nil saveData] The debugger will just breeze past the line. 调试器将轻松完成任务。

Generally, if something absolutely should not be nil , you can use NSAssert : 通常,如果绝对不应该为nil ,则可以使用NSAssert

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

But use this sparingly; 但是要谨慎使用; you'll probably come to usually appreciate this behaviour. 您可能通常会喜欢这种行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM