1

我有一个包含 UIStepper 的 UITableViewCell 子类。当用户与步进器交互时,我会触发一个 NSTimer,以便步进器将保存其值并在 2 秒内未再次更改该值时写入核心数据。

换一种方式:

UIStepper 包含在 UITableViewCell 中。
用户可以上下改变步进值。
每次触摸都会触发具有 2 秒延迟的计时器。
每次后续触摸都会使计时器无效。
将步进器单独放置 2 秒后,将保存更改。

这非常适合我需要它。问题是,如果我的用户非常快并且他们更改了值,然后弹出视图控制器并去做其他事情,2 秒计时器仍然没有触发,并且数据不是最新的以进行下一个操作。

为了使事情尽可能简单,我需要能够在该表视图单元格中判断(表)视图是否被弹出。然后我可以加快保存过程并确保数据是最新的并在任何其他操作发生之前保存。

4

6 回答 6

1

如果您想知道该表是否已弹出,请将您的清理/保存方法放入viewWillDisappear方法中。因为您正在使用计时器,dealloc所以您不想这样做,因此您没有任何意外的强参考周期。

从你的问题中不清楚,但我想确保你没有把你的细胞放在NSTimer你的UITableViewCell细胞上。显然,这是一个模型问题,而不是视图问题,而且表视图对出列和重用表视图单元格进行了各种优化。

其次,您必须跟踪数据的任何对象类(我ModelDataItem称之为我通过一个布尔值needSave)。因此,为了支持这一点,在我看来,您ModelDataItem可能至少应该具备以下四项:

(a) 引用其自己的计时器;

@property (nonatomic, strong) NSTimer *timer;

(b) 指示记录是否有挂起的保存操作的标志

@property (nonatomic) BOOL needSave;

(c) 每当对象的值更改(例如,值增加)时调用的方法,以安排在 2 秒内保存:

- (void)scheduleSave
{
    self.needSave = YES;

    if (self.timer)
        [self.timer invalidate];

    self.timer = [NSTimer scheduledTimerWithTimeInterval:2.0
                                                  target:self
                                                selector:@selector(save)
                                                userInfo:nil
                                                 repeats:NO];
}

(d) 您需要计时器调用的实际保存记录的方法:

- (void)save
{
    // do whatever you need to save the record

    NSLog(@"%s saving value=%@", __FUNCTION__, self.value);

    // now let's clean up the timer

    if (self.timer)
    {
        [self.timer invalidate];
        self.timer = nil;
    }

    self.needSave = NO;
}

然后,在您的表格视图控制器中,您应该:

(a) 当 stepperUIControlEventValueChanged被调用时,你显然应该改变你的数据模型,然后调用上述ModelDataItem方法scheduleSave

(b) 当表格视图被关闭时,应该立即保存任何未决的内容:

for (ModelDataItem *item in allModelDataItems)
{
    if (item.needSave)
        [item save];
}

请注意,在最后一点上,我不依赖于dealloc清理和保存需要保存的模型项目,因为计划NSTimer保留它target,因此dealloc不会被调用(或者至少在执行计时器之前不会被调用)。所以,我手动遍历它们并在我关闭视图时处理它。

于 2012-11-27T22:00:31.017 回答
0

您可以让您的自定义单元格侦听表格视图即将消失的通知,然后在viewWillDisappear您的视图控制器的方法中发布该通知。

于 2012-11-27T15:24:00.563 回答
0

当父 TableView 从我假设您正在使用的 NavigationController 中弹出时,TableView 应该被释放。此外,它的每个 TableViewCells 也应该被释放。

您可以使计时器无效并在 TableViewCell 的 dealloc 方法中处理任何挂起的更新。

在不改变设计的情况下,这就是我会尝试的。如果这被证明是有问题的,您还可以尝试在此值更改时设置某种与 TableView 的通信,并让 TableView 负责数据更新。

于 2012-11-27T15:24:08.660 回答
0

从您的描述中很难看出,但我认为您根本不需要使用计时器。您不能将步进器值分配给该类的属性或 ivar,然后在 viewDidDisappear 方法中将该值写入核心数据吗?

于 2012-11-27T16:59:08.973 回答
0

我发现过去最好的方法是将 UITableViewCell 子类设置为视图控制器的委托......然后在您的视图控制器中 viewDidDisappear 只需调用委托方法。

委托方法将在您的 UITableViewCell 子类中实现,并且只需调用您在两秒计时器完成时执行的相同代码。这类似于 Phillip 建议的通知方法,但如果您习惯于分配代表等,则更简洁一些。

于 2012-11-27T17:09:20.073 回答
0

只需覆盖 dealloc 方法并执行此操作。UITableViewCell 在弹出/卸载父视图时被释放。

于 2013-09-10T10:43:27.877 回答