0

在我的应用程序中,我有一个 UITableView 和 2 个按钮“保存”和“加载”。就我而言,当用户保存他或她的曲目时,我的 UITableView 会添加一个带有曲目标题的新单元格,然后当用户点击该单元格时,它将重新加载他们的曲目。这工作正常,但是每当用户保存一首曲目,然后尝试保存另一首曲目时,新添加的单元格只会重新加载一首曲目。因此,我的 tableview 可以有 10 个具有名称的单元格,但是每当您点击一个单元格时,只会保存一首曲目。所以我的问题是,如何保存每个单元格的数据?这是我的保存功能:

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:NSStringFromCGPoint(ball.center) forKey:@"ballPosition"];
[userDefaults synchronize];

NSUserDefaults *block1DF = [NSUserDefaults standardUserDefaults];
[block1DF setObject:NSStringFromCGPoint(block1.center) forKey:@"block1Position"];
[block1DF synchronize];

NSUserDefaults *block2DF = [NSUserDefaults standardUserDefaults];
[block2DF setObject:NSStringFromCGPoint(block2.center) forKey:@"block2Position"];
[block2DF synchronize];

NSUserDefaults *block3DF = [NSUserDefaults standardUserDefaults];
[block3DF setObject:NSStringFromCGPoint(block3.center) forKey:@"block3Position"];
[block3DF synchronize];

NSUserDefaults *winBlockDF = [NSUserDefaults standardUserDefaults];
[winBlockDF setObject:NSStringFromCGPoint(winBlock.center) forKey:@"winBlockPosition"];
[winBlockDF synchronize];

NSString *trackName = [[alertView textFieldAtIndex:0] text];
trackTitle.text = trackName;

[trackArray addObject:[NSString stringWithFormat:trackName,[trackArray count]+1]];
[self.myTableView reloadData];

然后我的 tableViewdidSelectRowAtIndexPath:

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
CGPoint ballPoint = CGPointFromString([userDefaults objectForKey:@"ballPosition"]);
[ball setCenter:ballPoint];

NSUserDefaults *block1DF = [NSUserDefaults standardUserDefaults];
CGPoint block1Point = CGPointFromString([block1DF objectForKey:@"block1Position"]);
[block1 setCenter:block1Point];

NSUserDefaults *block2DF = [NSUserDefaults standardUserDefaults];
CGPoint block2Point = CGPointFromString([block2DF objectForKey:@"block2Position"]);
[block2 setCenter:block2Point];

NSUserDefaults *block3DF = [NSUserDefaults standardUserDefaults];
CGPoint block3Point = CGPointFromString([block3DF objectForKey:@"block3Position"]);
[block3 setCenter:block3Point];

NSUserDefaults *winBlockDF = [NSUserDefaults standardUserDefaults];
CGPoint winBlockPoint = CGPointFromString([winBlockDF objectForKey:@"winBlockPosition"]);
[winBlock setCenter:winBlockPoint];
4

1 回答 1

1

您只能保存一份数据副本的原因不是因为您有错误。这是因为 NSUserDefaults 只能保存一个版本的“ballPosition”。每当您保存另一个“ballPosition”时,它将替换您现有的“ballPosition”。

我建议根本不使用 NSUserDefaults。通常,当您想要保存大量类似数据的版本时,您会使用 Core Data。

一个很好的教程在这里http://www.raywenderlich.com/934/core-data-on-ios-5-tutorial-getting-started但如果你想在这里快速概述它是:

如果您在 Xcode 中创建一个新项目,选择 Master-Detail Application 并选择 Use Core Data,您将拥有一个新的支持核心数据的应用程序。

此演示应用程序创建一个“事件”对象表,每个对象都有一个名为“时间戳”的属性。

每次点击添加按钮时,都会运行以下代码:

- (void)insertNewObject:(id)sender
{
    NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
    NSEntityDescription *entity = [[self.fetchedResultsController fetchRequest] entity];
    NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];

    // If appropriate, configure the new managed object.
    // Normally you should use accessor methods, but using KVC here avoids the need to add a custom class to the template.
    [newManagedObject setValue:[NSDate date] forKey:@"timeStamp"];

    // Save the context.
    NSError *error = nil;
    if (![context save:&error]) {
         // Replace this implementation with code to handle the error appropriately.
         // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
}

这将创建一个新的 Event 对象,设置关键 timeStamp 的当前日期,并将对象保存到本地数据库。

这里的一个巨大优势是您现在可以完美地使用 MVC 或模态视图控制器架构模式。你有一个完整的模式(和数据库)层,它独立于你的视图和控制器工作。

您还正确地使用了 UITableViews,您有一个 NSFetchedResultsController 可以让您的表格在任何更改时保持最新,并且您有一个单独的详细视图来显示表格中的项目。

使用 Core Data 需要牢记以下几点:

  1. 您有数据库的架构。您可以从 Xcode 中的 xcdatamodeld 文件编辑您的架构。您存储在模型中的任何内容都必须在此处定义。
  2. 如果您只是在搞乱,您可以在更改 xcdatamodel 时重新安装您的应用程序,它会正常工作,否则您需要处理迁移和不同版本的架构。
  3. 核心数据并不是最容易学习的工具,但是一旦你学会了它,你在创建应用程序时就会有一个更好的起点。
于 2013-07-02T23:27:49.620 回答