如何在iphone上使用归档功能保存数据?

时间:2010-09-06 16:28:47

标签: iphone objective-c

我在保存数据时遇到问题。

所需行为:

我在视图中定义了一个捕获用户输入的文本字段。单击提交按钮(内部触摸)时,我希望将该数据写入可变数组。到目前为止,我将在提交时归档该可变数组,但是一旦视图消失/卸载,它也会进行归档。当用户离开视图或退出应用程序并重新进入时,我想在文本字段中显示该可变数组的第一个元素。

实际行为:

Textfield会在提交时捕获数据并更新myMutableArray。我在视图上添加了一些标签和NSLog,以便在我点击提交时验证计数是否增长。然后我第一次归档这个,我看到我的文件现在存在于myDocuments中,当我重新访问视图并检查dataArray的数量时,如果该文件存在,则创建dataArray的数量,dataArray的数量与我创建的元素数量相匹配在myMutableArray中。如果我再次开始输入数据,它会重新重置myMutableArray和dataArray。这是我认为我遇到的几个问题之一。

问题:

如果文件存在,则创建dataArray。现在我尝试设置文本字段以显示第一个元素,程序炸弹!如果dataArray存在,并且我可以看到count是一些正值,我不明白为什么我无法访问第一个元素。

我觉得当我访问视图并进行此练习时,当我再次访问该视图时,我看到我有dataArray存在且具有正值,但是当我通过提交按钮再次开始添加文本时,我重置了所有内容!所以我可能会坚持一次,但随后擦干净。真正的持久性。我做错了什么?

最终,我将存储一些包含少量元素的记录。我将随着时间的推移创建多个记录供用户查看。存档是最好的方式吗?我应该开始使用NSCoding吗?

- (void)viewDidLoad {
    [super viewDidLoad];

    // Initialize mutable array and set equal to myMutableArray property

    NSMutableArray *aMutableArray = [[NSMutableArray alloc] init];
    myMutableArray = aMutableArray;

    // Debug Logging
    // NSLog(@"Mutable Array Count is: %i", [myMutableArray count]);

    NSFileManager *filemgr;
    NSString *docsDir;
    NSArray *dirPaths;

    filemgr = [NSFileManager defaultManager];

    // Get the documents directory

    dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    docsDir = [dirPaths objectAtIndex:0];

    // Build the path to the data file

    dataFilePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: @"data.archive"]];

    // Check if the file already exists

    if ([filemgr fileExistsAtPath: dataFilePath])
    {
        NSMutableArray *dataArray;

        dataArray = [NSKeyedUnarchiver unarchiveObjectWithFile: dataFilePath];
        myTextField.text = @"%@", [dataArray objectAtIndex:0];  // THIS BOMBS OUT MY PROGRAM FOR SURE IF INCLUDED!!!
        //myUpdatedMutableArray = dataArray;

        // Debug Logging

        NSLog(@"Mutable Array (dataArray) Count is: %i", [dataArray count]);
        //NSLog(@"The first value in the array is: %i", [dataArray objectAtIndex:0]);
    }
    [filemgr release];

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;
}



- (IBAction) mySubmitButtonPressed:(id)sender {

    // Debug Logging

    NSLog(@"Submit Button was Pressed!");
    NSLog(@"Mutable Array (myMutableArray) Count is: %i", [myMutableArray count]);

    // Create string from textfield and addobject to myMutableArray; check to see that myMutableArray grows in count

    NSString *myString = [[NSString alloc] initWithFormat:@"%@",myTextField.text];
    [myMutableArray addObject:myString];
    NSLog(@"Mutable Array (myMutableArray) Count is: %i", [myMutableArray count]);

    // More Debug Logging just using on-screen labels

    NSString *mySecondString = [[NSString alloc] initWithFormat:@"%i", [myMutableArray count]];
    myFirstLabel.text = myString;
    mySecondLabel.text = mySecondString;

    // Archive myMutableArray

    [NSKeyedArchiver archiveRootObject: myMutableArray toFile:dataFilePath];

    //[contactArray release];

}

1 个答案:

答案 0 :(得分:1)

此代码存在许多问题。

首先,你会在整个地方泄漏内存。具体在这里:

NSMutableArray *aMutableArray = [[NSMutableArray alloc] init];
myMutableArray = aMutableArray;

哪个应该是:

self.myMutableArray = [NSMutableArray array];

取消归档数据后,如果要将其保留在myMutableArray中,只需执行以下操作:

[myMutableArray appendArray: dataArray];

或者只是:

self.myMutableArray = dataArray;

你永远不应该释放像NSFileManager这样的单例实例,所以完全摆脱这个:

[fileMgr release];

您的代码崩溃,因为这不是有效的代码:

myTextField.text = @"%@", [dataArray objectAtIndex:0];

(它实际上是有效的代码,但它会做一些与你想象的截然不同的事情)

这不是Python,所以你必须这样做:

myTextField.text = [NSString stringWithFormat: @"%@",
    [dataArry objectAtIndex: 0]];

但这与以下内容完全相同:

myTextField.text = [dataArray objectAtIndex: 0];

mySubmitButtonPressed中向数组添加字符串可以比您想象的简单得多。就这样做:

[myMutableArray addObject: myTextField.text];

您应该了解自动释放的对象,内存管理以及保留属性实际执行的操作。