2010-09-06 106 views
0

我遇到了持久数据的问题。如何使用iphone上的归档功能保存数据?

所需的行为:

我在捕获用户输入的视图中定义的文本字段。当点击提交按钮(在里面修改)时,我希望将这些数据写入一个可变数组。到目前为止,我将在提交时将这个可变数组存档,但是一旦视图消失/卸载,也会进行归档。当用户从视图导航或退出应用程序并重新进入时,我想在文本字段中显示该可变数组的第一个元素。

实际行为:

文本字段采集数据和更新myMutableArray在提交。我在视图上加了一些标签,加上NSLog来验证计数随着我点击提交而增长。然后我第一次将它存档,我发现我的文件现在存在于myDocuments中,当我重新访问视图并检查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

这个代码有很多问题。

首先,你泄漏内存到处都是。具体位置:

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

你真的应该了解自动释放对象,内存管理什么保持性实际上做。

+0

让我给这个旋转。我是一名新秀,所以我正在努力学习,但非常感谢反馈。我会试着清理它,看看我的位置和后退。谢谢。 – newDeveloper 2010-09-06 17:37:04

+0

我已更新我的代码。现在它更加清洁,我不再覆盖持久性,它通过用户会话进行维护。 – newDeveloper 2010-09-07 03:00:18