繁体   English   中英

在导航控制器中按下“后退”按钮时,是否可能不取消分配视图控制器?

[英]is it possible to not dealloc a view controller when the back button is pressed in a navigation controller?

这是我的问题:我有一个带有一堆单元格的表视图。 核心数据使用NSFetchedResultsController将Task对象加载到单元格中。 现在我有了它,所以每个单元格都有一个DetailViewController,它像这样存储在字典中:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    DetailViewController *detailVC;
    if (![self.detailViewsDictionary.allKeys containsObject:@(indexPath.row)]){
        detailVC = [[DetailViewController alloc]initWithNibName:@"DetailViewController" bundle:nil];
        [self.detailViewsDictionary setObject:detailVC forKey:@(indexPath.row)];
    }else{
        detailVC = self.detailViewsDictionary[@(indexPath.row)];
    }
        Tasks *task = [[self fetchedResultsController] objectAtIndexPath:indexPath];
        detailVC.testTask = task;
        [[self navigationController] pushViewController:detailVC animated:YES];
}

每个DetailViewController都有一个timer属性,该属性从Task对象获取其时间间隔,该Task对象与tableview中任何给定索引路径上的单元格相关。 这是我的详细视图控制器的代码:

- (void)viewDidLoad {
    [super viewDidLoad];
    [NSThread detachNewThreadSelector:@selector(startTimer:) toTarget:self withObject:nil];
}
-(IBAction)startTimer:(id)sender{
//default value of showButtonValue when first loaded is 1
    if (testTask.showButtonValue == 1) {
        [startButton setTitle:@"Start" forState:UIControlStateNormal];
        timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];
        testTask.showButtonValue = 3;
    } else if (testTask.showButtonValue == 2) {
        [startButton setTitle:@"Resume" forState:UIControlStateNormal];
        [timer invalidate];
        timer = nil;
        testTask.showButtonValue = 3;
    } else if (testTask.showButtonValue == 3){
        [startButton setTitle:@"Pause" forState:UIControlStateNormal];
        timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];
        testTask.showButtonValue = 2;
    }
}
-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    nameTextField.text = testTask.taskName;
    [timerLabel setFont:[UIFont fontWithName:@"Arial" size:60]];
    NSUInteger seconds = (NSUInteger)round(testTask.timeInterval);
    NSString *string = [NSString stringWithFormat:@"%02u:%02u:%02u",
                        seconds / 3600, (seconds / 60) % 60, seconds % 60];
    timerLabel.text = string;
    [[self navigationItem] setTitle:[testTask taskName]];

    [timerLabel setNeedsDisplay];
    [self.view setNeedsDisplay];
}
-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    testTask.taskName = nameTextField.text;
}
-(void)timerAction:(NSTimer *)t
{
    if(testTask.timeInterval == 0)
    {
        if (self.timer)
        {
            [self timerExpired];
            [self.timer invalidate];
            self.timer = nil;
        }
    }
    else
    {
        testTask.timeInterval--;
    }
    NSUInteger seconds = (NSUInteger)round(testTask.timeInterval);
    NSString *string = [NSString stringWithFormat:@"%02u:%02u:%02u",
                        seconds / 3600, (seconds / 60) % 60, seconds % 60];
    timerLabel.text = string;
    NSLog(@"%f", testTask.timeInterval);
}

无论详细视图控制器当前是否在屏幕上,都应设置计时器以继续运行。 当我第一次点击一个单元格时,转到详细信息视图控制器并启动计时器,然后返回到表格视图,这没有问题,倒计时还在继续。 问题是,如果我重新轻按该单元格,则会创建另一个计时器,因此时间递减两倍快! 不仅如此,显示剩余时间的字符串不会在ViewWillAppear上更新,而只会在第一次调用timerAction时更新。

有很多问题,我真的很感谢您的帮助!

您在didSelectRowAtIndexPath中拥有的代码(我在对其他问题的回答中提供了此信息)( 每个详细信息视图控制器一个计时器 ),当您按下返回按钮时,确实防止了该控制器的释放。 它通过在字典中保留对详细视图控制器的引用来做到这一点。 我猜它对您不起作用,因为您忘了初始化字典,所以它为零。

即使问题已经回答,我也要发表自己的看法。 乍看起来,我可能是错的,但是我认为防止解除分配不是一个好主意,尤其是对于整个控制器而言。 在iOS中,必须尽快释放内存。

但是,通过查看您的代码,我将无能为力。

  • 将标签创建移至viewDidLoad,并在viewWillAppear中更新其内容
  • 将计时器的创建和启动放入实用程序类中,并使用适当的方法来启动,停止和暂停给定的计时器。 该类将确保仅运行一个(或多个具有指定ID的)计时器,并且控制器可以要求它。 它并不是很优雅,但是您至少可以为此使用AppDelegate。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM