简体   繁体   English

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

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

Here is my issue: I have a tableview with a bunch of cells. 这是我的问题:我有一个带有一堆单元格的表视图。 Core Data loads Task object into the cells using NSFetchedResultsController. 核心数据使用NSFetchedResultsController将Task对象加载到单元格中。 Right now I have it so each cell has a DetailViewController, which is stored in a dictionary like so: 现在我有了它,所以每个单元格都有一个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];
}

Each DetailViewController has a timer property that gets its time interval from the Task object which correlates to the cell at any given index path in the tableview. 每个DetailViewController都有一个timer属性,该属性从Task对象获取其时间间隔,该Task对象与tableview中任何给定索引路径上的单元格相关。 Here is the code I have for my detail view controller: 这是我的详细视图控制器的代码:

- (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);
}

The timer is SUPPOSED to keep on going regardless of whether the detail view controller is currently on the screen or not. 无论详细视图控制器当前是否在屏幕上,都应设置计时器以继续运行。 When I tap a cell for the first time, go to the detail view controller and start the timer, and then go BACK to the tableview, there is no problem and the countdown keeps on going. 当我第一次点击一个单元格时,转到详细信息视图控制器并启动计时器,然后返回到表格视图,这没有问题,倒计时还在继续。 The PROBLEM is that if I re-tap the cell, another timer is created so the time decrements 2x as fast! 问题是,如果我重新轻按该单元格,则会创建另一个计时器,因此时间递减两倍快! Not only that, but the string which displays the remaining time doesn't update upon ViewWillAppear, it only updates the first time timerAction is called. 不仅如此,显示剩余时间的字符串不会在ViewWillAppear上更新,而只会在第一次调用timerAction时更新。

There are a bunch of issues, I really would appreciate some help! 有很多问题,我真的很感谢您的帮助!

The code you have in didSelectRowAtIndexPath, which I provided in my answer to your other question ( one timer per detail view controller ), does prevent the controller from being deallocated when you press the back button. 您在didSelectRowAtIndexPath中拥有的代码(我在对其他问题的回答中提供了此信息)( 每个详细信息视图控制器一个计时器 ),当您按下返回按钮时,确实防止了该控制器的释放。 It does this by keeping a reference to the detail view controller in a dictionary. 它通过在字典中保留对详细视图控制器的引用来做到这一点。 I'm guessing that it's not working for you because you forgot to initialize the dictionary, so it's nil. 我猜它对您不起作用,因为您忘了初始化字典,所以它为零。

I am giving my opinion even if question has been answered. 即使问题已经回答,我也要发表自己的看法。 Onestly, I may be wrong, but I don't think that preventing deallocation is a good idea, especially of a whole controller. 乍看起来,我可能是错的,但是我认为防止解除分配不是一个好主意,尤其是对于整个控制器而言。 In iOS, memory has to be released as soon as possible. 在iOS中,必须尽快释放内存。

However, by seeing your code, I would do few things. 但是,通过查看您的代码,我将无能为力。

  • Move label creation to viewDidLoad, and update its content in viewWillAppear 将标签创建移至viewDidLoad,并在viewWillAppear中更新其内容
  • Put your timer creation and launch within a utility class, with proper methods to start, stop, pause a given timer. 将计时器的创建和启动放入实用程序类中,并使用适当的方法来启动,停止和暂停给定的计时器。 The class will ensure there's only one (or more with an assigned ID) timer running, and controller can ask for it. 该类将确保仅运行一个(或多个具有指定ID的)计时器,并且控制器可以要求它。 It's not really elegant, but you can at least use the AppDelegate for this. 它并不是很优雅,但是您至少可以为此使用AppDelegate。

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

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