ios - UITableView Cell 无法正确保存数据?

标签 ios uitableview nsuserdefaults

在我的应用程序中,我有一个 UITableView 和 2 个按钮“保存”和“加载”。就我而言,当用户保存他或她的轨道时,我的 UITableView 添加一个带有轨道标题的新单元格,然后当用户点击该单元格时,它将重新加载他们的轨道。这工作正常,但每当用户保存一个轨道,然后尝试保存另一个轨道时,新添加的单元只会重新加载一个轨道。因此,我的表格 View 可以有 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];

然后是我的tableView didSelectRowAtIndexPath:

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

最佳答案

您只能保存一份数据副本的原因并不是因为您有错误。这是因为 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”,您将拥有一个新的核心数据支持的应用程序。

此演示应用程序创建一个“Event”对象表,每个对象都有一个名为“timestamp”的属性。

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

- (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 对象,设置关键时间戳的当前日期,并将该对象保存到本地数据库。

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

您还正确使用了 UITableViews,您有一个 NSFetchedResultsController,它将在任何更改时使您的表保持最新,并且您有一个单独的详细信息 View 来显示表中的项目。

使用核心数据需要记住的一些事项:

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

关于ios - UITableView Cell 无法正确保存数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17436405/

相关文章:

ios - AudioServicesPlaySystemSound 不播放,除非我跨过

swift - 测验应用程序 : Saving selected quiz-questions using NSUserDefaults and displaying it in another view controller

ios - 存储应用程序运行时间的值

ios - UITableView 滚动到底部时显示 "loading spinner"

ios - Swift UI 测试无法在 iOS 12.3 之前的设备上启动

ios - 在 Swift 中通过不同的类调用委托(delegate)方法

ios - NSURLConnection延迟导致没有图片的空UItableViewCell

ios - dispatch_async() block 在 UITableViewDataSource 方法之前没有完成

xcode - 核心数据 : bundle. main.url 意外(突然)返回 NIL

ios - XIB 中的 UIViewController?