Почему popViewController только работает каждое второе время

Когда текстовое поле в ячейке сфокусировано, то первым респондентом является редактор поля текстового поля. Используйте row(for:) и column(for:) из NSTableView, чтобы получить строку и столбец.

if let view = window.firstResponder as? NSView {
    let column = tableView.column(for: view)
    let row = tableView.row(for: view)
}
6
задан Tim Bowen 4 May 2009 в 02:25
поделиться

4 ответа

Можете ли вы попробовать и отладить ваше приложение, чтобы увидеть, где находится элемент управления при вызове updateCells? Похоже, что-то не так с приложением.

Убедитесь, что в памяти нет ни одного предупреждения памяти, пока вы находитесь в классе LoadingViewController. Если в памяти появляется предупреждение и ваше представление RootViewController освобождается, то viewDidLoad будет вызываться снова, когда вы выполняете всплывающее окно в RootViewController.

Сохраняйте точки останова в viewDidLoad и updateCells. Вы уверены, что не вызываете LoadingViewController где-либо еще?

представление s освобождается, тогда viewDidLoad будет вызываться снова, когда вы выполняете всплывающее окно в RootViewController.

Сохраняйте точки останова в viewDidLoad и updateCells. Вы уверены, что не вызываете LoadingViewController где-либо еще?

представление s освобождается, тогда viewDidLoad будет вызываться снова, когда вы выполняете всплывающее окно в RootViewController.

Сохраняйте точки останова в viewDidLoad и updateCells. Вы уверены, что не вызываете LoadingViewController где-либо еще?

0
ответ дан 17 December 2019 в 22:14
поделиться

Первая мысль заключается в том, что вы можете не захотеть отправлять startUpdatingLocation в CLLocationManager до тех пор, пока не нажмете свое представление загрузки. Часто первое сообщение -locationManager: didUpdateToLocation: fromLocation: появляется мгновенно с кэшированными данными GPS. Это имеет значение только в том случае, если вы обрабатываете каждое сообщение и не фильтруете данные GPS, как показано в примере кода здесь. Однако это не приведет к описанной вами ситуации - это приведет к зависанию экрана загрузки.

Я испытал подобное странное поведение в другой ситуации, когда я пытался открыть корневой контроллер представления. при переключении на другую вкладку и вызов не в нужном месте. Я считаю, что для меня дважды вызывали popToRootViewController. Я подозреваю, что ваше представление загрузки либо нажимается дважды, либо всплывает дважды.

Я рекомендую реализовать -viewWillAppear :, -viewDidAppear :, -viewWillDisappear: и -viewDidDisappear: с минимальной регистрацией в вашем LoadingViewController.

- (void)viewWillAppear:(BOOL)animated {
    NSLog(@"[%@ viewWillAppear:%d]", [self class], animated);
    [super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated {
    NSLog(@"[%@ viewDidAppear:%d]", [self class], animated);
    [super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated {
    NSLog(@"[%@ viewWillDisappear:%d]", [self class], animated);
    [super viewWillDisappear:animated];
}

- (void)viewDidDisappear:(BOOL)animated {
    NSLog(@"[%@ viewDidDisappear:%d]", [self class], animated);
    [super viewDidDisappear:animated];
}

Затем запустите тест на своем устройстве, чтобы узнать, всегда ли они отправляются на ваш контроллер представления и как часто. Вы можете добавить запись в -updateClicked, чтобы отображать двойные касания.

Еще одна мысль: хотя ваш блок @synchronized - хорошая идея, он будет только удерживать другие потоки от выполнения этих операторов до тех пор, пока первый поток не выйдет из блока. Я предлагаю переместить сообщение -stopUpdatingLocation в качестве первого оператора внутри этого блока @synchronized. Таким образом, как только вы решите действовать с некоторыми новыми данными GPS, вы сразу же скажете CLLocationManager прекратить отправку новых данных.

-viewDidAppear :, -viewWillDisappear: и -viewDidDisappear: с минимальной регистрацией в вашем LoadingViewController.

- (void)viewWillAppear:(BOOL)animated {
    NSLog(@"[%@ viewWillAppear:%d]", [self class], animated);
    [super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated {
    NSLog(@"[%@ viewDidAppear:%d]", [self class], animated);
    [super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated {
    NSLog(@"[%@ viewWillDisappear:%d]", [self class], animated);
    [super viewWillDisappear:animated];
}

- (void)viewDidDisappear:(BOOL)animated {
    NSLog(@"[%@ viewDidDisappear:%d]", [self class], animated);
    [super viewDidDisappear:animated];
}

Затем запустите тест на своем устройстве, чтобы узнать, всегда ли они отправляются на ваш контроллер представления и как часто. Вы можете добавить запись в -updateClicked, чтобы отображать двойные касания.

Еще одна мысль: хотя ваш блок @synchronized - хорошая идея, он будет только удерживать другие потоки от выполнения этих операторов до тех пор, пока первый поток не выйдет из блока. Я предлагаю переместить сообщение -stopUpdatingLocation в качестве первого оператора внутри этого блока @synchronized. Таким образом, как только вы решите действовать с некоторыми новыми данными GPS, вы сразу же скажете CLLocationManager прекратить отправку новых данных.

-viewDidAppear :, -viewWillDisappear: и -viewDidDisappear: с минимальной регистрацией в вашем LoadingViewController.

- (void)viewWillAppear:(BOOL)animated {
    NSLog(@"[%@ viewWillAppear:%d]", [self class], animated);
    [super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated {
    NSLog(@"[%@ viewDidAppear:%d]", [self class], animated);
    [super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated {
    NSLog(@"[%@ viewWillDisappear:%d]", [self class], animated);
    [super viewWillDisappear:animated];
}

- (void)viewDidDisappear:(BOOL)animated {
    NSLog(@"[%@ viewDidDisappear:%d]", [self class], animated);
    [super viewDidDisappear:animated];
}

Затем запустите тест на своем устройстве, чтобы узнать, всегда ли они отправляются на ваш контроллер представления и как часто. Вы можете добавить запись в -updateClicked, чтобы отображать двойные касания.

Еще одна мысль: хотя ваш блок @synchronized - хорошая идея, он будет только удерживать другие потоки от выполнения этих операторов до тех пор, пока первый поток не выйдет из блока. Я предлагаю переместить сообщение -stopUpdatingLocation в качестве первого оператора внутри этого блока @synchronized. Таким образом, как только вы решите действовать с некоторыми новыми данными GPS, вы сразу же скажете CLLocationManager прекратить отправку новых данных.

запустите тест на своем устройстве, чтобы узнать, всегда ли они отправляются на ваш контроллер представления и как часто. Вы можете добавить запись в -updateClicked, чтобы отображать двойные касания.

Еще одна мысль: хотя ваш блок @synchronized - хорошая идея, он будет только удерживать другие потоки от выполнения этих операторов до тех пор, пока первый поток не выйдет из блока. Я предлагаю переместить сообщение -stopUpdatingLocation в качестве первого оператора внутри этого блока @synchronized. Таким образом, как только вы решите действовать с некоторыми новыми данными GPS, вы сразу же скажете CLLocationManager прекратить отправку новых данных.

запустите тест на своем устройстве, чтобы узнать, всегда ли они отправляются на ваш контроллер представления и как часто. Вы можете добавить запись в -updateClicked, чтобы отображать двойные касания.

Еще одна мысль: хотя ваш блок @synchronized - хорошая идея, он будет только удерживать другие потоки от выполнения этих операторов до тех пор, пока первый поток не выйдет из блока. Я предлагаю переместить сообщение -stopUpdatingLocation в качестве первого оператора внутри этого блока @synchronized. Таким образом, как только вы решите действовать с некоторыми новыми данными GPS, вы сразу же скажете CLLocationManager прекратить отправку новых данных.

он будет только удерживать другие потоки от выполнения этих операторов, пока первый поток не выйдет из блока. Я предлагаю переместить сообщение -stopUpdatingLocation в качестве первого оператора внутри этого блока @synchronized. Таким образом, как только вы решите действовать с некоторыми новыми данными GPS, вы сразу же скажете CLLocationManager прекратить отправку новых данных.

он будет только удерживать другие потоки от выполнения этих операторов, пока первый поток не выйдет из блока. Я предлагаю переместить сообщение -stopUpdatingLocation в качестве первого оператора внутри этого блока @synchronized. Таким образом, как только вы решите действовать с некоторыми новыми данными GPS, вы сразу же скажете CLLocationManager прекратить отправку новых данных.

1
ответ дан 17 December 2019 в 22:14
поделиться
​​

Глядя на ваш исходный код, я очень подозреваю, что этот блок очень сильно:

- (void)viewDidLoad {
    ...
    lv = [[LoadingViewController alloc] initWithNibName:@"Loading" bundle:nil];
    [self.navigationController pushViewController:lv animated:YES];
    [super viewDidLoad];
 }

viewDidLoad вызывается каждый раз, когда загружается NIB, что может происходить несколько раз, особенно если у вас заканчивается в памяти (что кажется вероятным, учитывая ваше замечание, что это происходит только на устройстве). Я рекомендую вам реализовать -didReciveMemoryWarning и после вызова super, по крайней мере, распечатать журнал, чтобы вы могли видеть, происходит ли это с вами.

В приведенном выше коде меня беспокоит то, что у вас почти наверняка происходит утечка lv , а это означает, что количество работающих LoadingViewControllers может увеличиваться. Вы говорите, что это переменная класса. Вы действительно имеете в виду, что это переменная экземпляра? ivars всегда должен использовать методы доступа ( self. lv или [self lv] , а не lv ). Не назначайте их напрямую; вы почти всегда будете делать это неправильно (так как здесь вы, скорее всего, ошибаетесь).

0
ответ дан 17 December 2019 в 22:14
поделиться

Итак, мне так и не удалось заставить это работать. Я наблюдаю такое поведение на устройстве только каждый раз, когда программно вызываю popViewController, вместо того, чтобы позволить кнопке возврата по умолчанию на контроллере навигации делать всплывающие окна.

Моим обходным решением было создать пользовательское представление загрузки и переворачивать экран в это представление каждый раз будет задержка из-за доступа в Интернет. Мой метод принимает логическую переменную yes или no - yes переключает на экран загрузки, а no переключает обратно к нормальному виду. Вот код:

- (void)switchViewsToLoading:(BOOL)loading {
// Start the Animation Block  
CGContextRef context = UIGraphicsGetCurrentContext();  
[UIView beginAnimations:nil context:context];  
[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromLeft forView:self.tableView cache:YES];  
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];  
[UIView setAnimationDuration:.75];  

// Animations  
if(loading) { 
    if (lv == nil) { lv = [[LoadingViewController alloc] initWithNibName:@"Loading" bundle:nil]; }
    [self.view addSubview:lv.view];
    [self.view sendSubviewToBack:self.tableView];
    self.title = @"TrailBehind";
}
else {
    [lv.view removeFromSuperview];

}
// Commit Animation Block  
[UIView commitAnimations];  
//It looks kind of dumb to animate the nav bar buttons, so set those here
if(loading) {
    self.navigationItem.rightBarButtonItem = nil;
    self.navigationItem.leftBarButtonItem = nil;
    self.title = @"TrailBehind";
}
else {
    UIBarButtonItem *feedback = [[UIBarButtonItem alloc] initWithTitle:@"Feedback" style:UIBarButtonItemStylePlain target:self action:@selector(feedbackClicked)];
    self.navigationItem.rightBarButtonItem = feedback;
    UIBarButtonItem *update = [[UIBarButtonItem alloc] initWithTitle:@"Move Me" style:UIBarButtonItemStylePlain target:self action:@selector(updateClicked)];
    self.navigationItem.leftBarButtonItem = update;
    [feedback release];
    [update release];
}

}

0
ответ дан 17 December 2019 в 22:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: