Ios UITableView单元格未正确保存数据?

Ios UITableView单元格未正确保存数据?,ios,uitableview,nsuserdefaults,Ios,Uitableview,Nsuserdefaults,在我的应用程序中,我有一个UITableView和两个按钮“保存”和“加载”。在我的例子中,当用户保存他或她的曲目时,我的UITableView会添加一个带有曲目标题的新单元格,然后当用户点击该单元格时,它会重新加载他们的曲目。这工作正常,但每当用户保存一个曲目,然后尝试保存另一个曲目时,新添加的单元格只重新加载一个曲目。因此,我的tableview可以有10个有名称的单元格,但只要点击其中一个单元格,就会只保存一个曲目。所以我的问题是,如何保存每个单元格的数据?以下是我的保存功能: NSUse

在我的应用程序中,我有一个UITableView和两个按钮“保存”和“加载”。在我的例子中,当用户保存他或她的曲目时,我的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];
然后我的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];

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

我建议根本不要使用NSUserDefaults。通常,当您想要保存许多版本的类似数据时,您需要使用核心数据

这里有一个很好的教程,但如果您想快速了解这里的概况,请参阅:

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

这个演示应用程序创建了一个“事件”对象表,每个对象都有一个名为“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();
    }
}
这将创建一个新的事件对象,设置密钥时间戳的当前日期,并将对象保存到本地数据库

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

您还可以正确使用UITableView,您有一个NSFetchedResultsController,它可以在任何更改时使表保持最新,并且您有一个单独的详细信息视图来显示表中的项目

关于核心数据,需要记住以下几点:

  • 您的数据库有一个模式。您可以从Xcode中的xcdatamodeld文件编辑模式。存储在模型中的任何内容都必须在此处定义
  • 如果你只是胡闹,你可以在任何时候更改你的xcdatamodel重新安装你的应用程序,它会很好地工作,否则你需要处理迁移和不同版本的模式
  • 核心数据不是最容易学习的工具,但一旦你学会了,你在创建应用程序时就会有一个更好的起点

  • 我有一个更好的问题,我们如何在没有看到源代码的情况下解决您的问题?请发布相关代码,以便我们检查,并可能发现问题;)保留有问题的代码片段,而不是注释。这段代码太可怕了。1.)除非您立即需要这些值,否则不需要调用
    synchronize
    。2.)您不需要为尝试存储的每个值创建一个新的/单独的
    NSUserDefaults
    实例。您的代码基本上可以简化为以下内容:在看到这段新代码后,我确实意识到我的代码过于草率,没有必要。我现在如何解决我的问题?很抱歉,我是一名年轻的开发人员。我才14岁。非常感谢您的帮助,但请不要说我的代码很糟糕。您需要用新的或删除的对象重新加载
    trackArray
    数组。重新加载数组后,在表上调用
    reloadData
    。您提供的所有userDefaults的代码与您正在寻找的内容没有任何关系。我真的很感激这一点,但我真的不想重新启动整个项目。有没有办法在单视图应用程序中实现这一点?我已经导入了CoreData框架,您当然可以,我链接的教程中有一些步骤。基本上,您需要添加一个xcdatamodald文件,创建一个NSFetchedResults控制器,等等。我只需要从您创建的新项目导入代码。