我有一个包含UIStepper的UITableViewCell子类。当用户与步进器交互时,我会触发NSTimer,以便步进器保存其值并写入Core Data,如果该值在2秒内没有再次更改。
换句话说:
UIStepper包含在UITableViewCell中 用户可以上下改变步进值 每次触摸都会触发计时器,延迟时间为2秒 每次后续触摸都会使计时器无效 当步进器单独放置2秒钟时,保存更改。
这非常适合我需要的东西。问题是,如果我的用户非常快并且他们更改了值,那么弹出视图控制器并继续执行其他操作,2秒计时器仍然没有触发,并且数据不是最新的下一个操作。
为了使事情尽可能简单,我需要能够在该表视图单元格中告知是否弹出了(表格)视图。然后,我可以加快保存过程,确保数据是最新的,并在执行任何其他操作之前保存。
答案 0 :(得分:1)
如果要判断表是否已弹出,请将清理/保存方法放在viewWillDisappear
方法中。因为您正在使用计时器,所以您不希望这样做dealloc
,因此您没有任何意外的强引用周期。
您的问题并不清楚,但我希望确保您没有将NSTimer
放在UITableViewCell
单元格上。显然,这是一个模型问题,而不是 view 问题,但表视图也会对出列和重用表视图单元格进行各种优化。
其次,你必须跟踪数据的对象类(我称之为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)当调用步进器的UIControlEventValueChanged
时,您显然应该更改数据模型,然后调用上面的ModelDataItem
方法scheduleSave
;
(b)当表格视图被驳回时,应该可以立即保存待处理的任何内容:
for (ModelDataItem *item in allModelDataItems)
{
if (item.needSave)
[item save];
}
注意,关于最后一点,我不依赖于dealloc
来清理和保存需要保存的模型项,因为预定的NSTimer
会保留其target
,因此dealloc
将不会接到电话(或至少在执行定时器之前)。因此,当我解除视图时,我手动迭代它们并处理它。
答案 1 :(得分:0)
您可以让自定义单元格侦听表视图正在消失的通知,然后在视图控制器的viewWillDisappear
方法中发布该通知。
答案 2 :(得分:0)
当我假设您正在使用的NavigationController中弹出父TableView时,应该释放TableView。此外,每个TableViewCells也应该被解除分类。
您可以使计时器无效并处理TableViewCell的dealloc方法中的任何挂起更新。
在不改变设计的情况下,我会尝试这样做。如果这证明是有问题的,那么当这个值发生变化并让TableView负责数据更新时,您也可以尝试将某种通信设置回TableView。
答案 3 :(得分:0)
很难从你的描述中看出来,但我认为你根本不需要使用计时器。你不能只将该步进值分配给该类的属性或ivar,然后在viewDidDisappear方法中,将该值写入核心数据吗?
答案 4 :(得分:0)
我发现过去最好的方法是将UITableViewCell子类设置为视图控制器的委托...然后在视图控制器viewDidDisappear中调用委托方法。
委托方法将在您的UITableViewCell子类中实现,并且只需调用您的两秒计时器完成时所执行的相同代码。这类似于Phillip建议的通知方法,但如果您习惯于分配代表等,则会更加清晰。
答案 5 :(得分:0)
只需覆盖dealloc方法并执行操作。当弹出/卸载父视图时,将取消分配UITableViewCell。