Уволить UIAlertView после завершения задачи - PullRequest
0 голосов
/ 26 июля 2011

В моем приложении есть страница расширенного поиска, которая использует табличное представление с 4 ячейками для доступа к 4 табличным представлениям в виде раскрывающихся полей. Они заполняются из результатов анализа XML-файла, полученного мной по URL-запросу, который происходит при первой загрузке приложения и сохраняется в appDelegate, к которому позднее таблицы обращаются при доступе к странице расширенного поиска. В нормальных, хороших условиях подключения к интернету на это уходит доли секунды, поэтому информация там находится далеко до объявления. Страница поиска может быть даже доступна, но я хочу скрыть себя в случае очень медленного соединения. Итак, я помещаю представление оповещения с помощью спиннера на страницу расширенного поиска, если установленный мной флаг равен false (данные все еще запрашиваются / анализируются). Я смог заставить это работать, и у меня была кнопка отмены, возвращающая пользователя на предыдущую страницу в случае, если он не хотел ждать. Но мне также нужно, чтобы предупреждение было отклонено, если флаг поменяется на true (что означает, что разбор выполнен), и именно здесь у меня начинаются проблемы. Я запускаю бесконечный цикл, чтобы постоянно проверять, является ли флаг истинным, а затем отключаю оповещение, когда оно выходит из него. Я поместил его в отдельный поток, чтобы цикл не блокировал возможность пользователя нажимать кнопку отмены, но я получаю всевозможные ошибки времени выполнения:

- [UIAlertView dismissWithClickedButtonIndex: animated:]: сообщение отправлено на освобожденный экземпляр 0x105330

Вот соответствующий код:

-(void)viewDidAppear:(BOOL)animated
{
    [NSThread detachNewThreadSelector:@selector(waitTilDone) toTarget:self withObject:nil];
}

-(void)waitTilDone{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    while (mainDelegate.artistDone == @"no" || mainDelegate.mediumDone == @"no" || mainDelegate.seriesDone == @"no" || mainDelegate.areaDone == @"no") {
    }
    [av dismissWithClickedButtonIndex:0 animated:YES];
    [pool release];
}

-(void)viewDidLoad 
{    
    mainDelegate = (PublicArtOmahaAppDelegate*)[[UIApplication sharedApplication]delegate];

    if (mainDelegate.artistDone == @"no" || mainDelegate.mediumDone == @"no" || mainDelegate.seriesDone == @"no" || mainDelegate.areaDone == @"no") {
         av=[[UIAlertView alloc] initWithTitle:@"Loading Form Data" message:@"\n" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:nil];
        UIActivityIndicatorView *ActInd=[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
        [ActInd startAnimating];
        [ActInd setFrame:CGRectMake(125, 40, 37, 37)];
        [av addSubview:ActInd];
        [av show];
        [av release];
        }
    [super viewDidLoad];
}

- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    // the user clicked on the Cancel button
    [self dismissModalViewControllerAnimated:YES];
}

Итак, мои вопросы:

  1. Является ли бесконечный цикл дерьмовым способом проверки, могу ли я его отклонить? Мне нужно как-то это сделать ...: /

  2. Очевидно, что я плохо управляю памятью, но я довольно новичок в этом, поэтому я не знаю, что делаю неправильно. Там есть быстрое решение?

1 Ответ

1 голос
/ 26 июля 2011

Для 1): Да, это безумие. Используйте наблюдение ключа / значения (KVO), [NSNotificationCenter defaultCenter], напишите свой собственный делегат или что-то еще, чтобы получать уведомление о фактическом изменении значения, вместо того, чтобы опрашивать его.

Для 2): не отпускайте его, пока не закончите. Свойства могут быть полезны здесь, так как это упрощает многие вещи.

// In header
@property (nonatomic, retain) UIAlertView *av;

// When showing it
self.av = [[[UIAlertView alloc] initWith....] autorelease];
...

// When dismissing it
[self.av dismiss];
self.av = nil;
...