Iphone 跟踪UITableViewCells

Iphone 跟踪UITableViewCells,iphone,ios,objective-c,uitableview,Iphone,Ios,Objective C,Uitableview,我有一个待办事项列表应用程序,里面有很多任务。每个任务都有一个UITableViewCell。点击每个表视图单元格后,它将创建一个视图控制器,其中任务位于该行的索引路径属性处。这些视图控制器都存储在NSDictionary中。这是我刚才所说的代码表示: -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ DetailViewController *detai

我有一个待办事项列表应用程序,里面有很多任务。每个任务都有一个UITableViewCell。点击每个表视图单元格后,它将创建一个视图控制器,其中任务位于该行的索引路径属性处。这些视图控制器都存储在NSDictionary中。这是我刚才所说的代码表示:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    DetailViewController *detailVC;
    if (![self.detailViewsDictionary.allKeys containsObject:indexPath]){
        detailVC = [[DetailViewController alloc]initWithNibName:@"DetailViewController" bundle:nil];
        [self.detailViewsDictionary setObject:detailVC forKey:indexPath];
        detailVC.context = self.managedObjectContext;
    }else{
        detailVC = self.detailViewsDictionary[indexPath];
    }
        Tasks *task = [[self fetchedResultsController] objectAtIndexPath:indexPath];
        detailVC.testTask = task;
        [[self navigationController] pushViewController:detailVC animated:YES];
    NSLog(@"%@", self.detailViewsDictionary);
}
因此,这种创建唯一视图控制器并使用某个键存储它们的方法几乎总是有效的。删除或移动视图控制器时会出现问题:

我的印象是,当你向下滚动(退出队列)时,一个单元格的数据会被回收。这意味着使用数字标识符标记每个单元格将导致多个单元格具有相同的标识符

此外,如果使用indexPath键存储每个视图控制器,如何确保该键未设置为两个视图控制器。。?例如假设有4个单元格,这意味着有4个视图控制器。删除单元格3。单元格4向下移动到单元格3s点。您将创建一个新单元,该单元将转到点4。现在您有了两个具有相同indexPath密钥的控制器!你如何避免这种情况??它现在把我的应用搞砸了,因为已经移动的任务正在错误的视图控制器/单元格中加载它们的属性

以前有人建议我这样做是为了解决这个问题:“您维护一个NSMutableArray,它“隐藏”表的内容。”也有人建议我使用标记。然而,我不明白如何实现这些

编辑:---随机字符串--- 在tasks.m中

-(NSString *)uniqueIdentifierString{
    static NSString *alphabet  = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXZY0123456789";
    NSMutableString *s = [NSMutableString stringWithCapacity:20];
    for (NSUInteger i = 0U; i < 20; i++) {
        u_int32_t r = arc4random() % [alphabet length];
        unichar c = [alphabet characterAtIndex:r];
        [s appendFormat:@"%C", c];
    }
    return s;
}

一种解决方案是将VCs与表格单元格分离。您可以将VCs存储在字典中,由任务唯一的ID引用,但不必担心表单元格。如果任务被移动或删除,您可以在别处处理,而不用担心VC数组会立即出错

您的另一个选项是将遍历VC数组的逻辑挂接到move/edit方法中,以便在此时调整数组

鉴于
UITableView
期望单元格被重用,您可以看到它不打算成为其他数据的存储机制


最好将数据解耦,这样您就不会被绑定到数据的顺序或存在性上。

您能否澄清为什么每次点击单元格时都需要创建并保留视图控制器?这是一种非常占用内存的方法。如果我们知道你为什么需要这样做,那么排除(或加入)一些可能的解决方案会有帮助。好的。主视图控制器是tableView控制器。用户创建的每个任务在tableView中都有一个单元格。当用户点击单元格(任务)时,其属性将加载到详细视图控制器中。每个详图视图控制器都有一个计时器,并根据任务(单元格)的属性进行自定义。我需要创建并保持细节视图控制器,以便多个计时器可以同时运行。我不认为这会在内存方面造成太大差异,因为用户最多可能只有15个视图控制器。我的应用程序在内存维护方面非常低,几乎不使用任何内存,所以应该可以。此外,视图控制器需要保持不变,因为如果没有,当用户点击“后退”按钮时,视图将取消分配,如果他们想再次启动,计时器基本上会重复。关于你的第一个建议,这与我现在所做的有什么区别?只是因为我用indexath的键存储VCs,而indexath是表单元格的一部分吗?是的,因为indexath在您的控制之外会发生更改,这会导致问题。您甚至可以将taskID存储在tableViewCell中(尽管我不建议这样做)。然后,即使indexPath发生了变化,您仍然可以获得taskID。好的,谢谢,我现在理解了这个问题。但在我做任何事情之前,您认为为每个任务提供唯一ID的最佳方法是什么?如果这些任务只是设备的本地任务,您可以生成一个足够长的随机字符串。令人惊叹的。我去看看。
   -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    DetailViewController *detailVC;
     Tasks *task = [[self fetchedResultsController] objectAtIndexPath:indexPath];
    if (![self.detailViewsDictionary.allKeys containsObject:task.uniqueIdentifierString]){
        detailVC = [[DetailViewController alloc]initWithNibName:@"DetailViewController" bundle:nil];
        [self.detailViewsDictionary setObject:detailVC forKey:task.uniqueIdentifierString];
        detailVC.context = self.managedObjectContext;
    }else{
        detailVC = self.detailViewsDictionary[task.uniqueIdentifierString];
    }
        detailVC.testTask = task;
        [[self navigationController] pushViewController:detailVC animated:YES];
    NSLog(@"%@", detailVC);
    NSLog(@"%@", task.uniqueIdentifierString);
}