2

Я пытаюсь отобразить UIAlertView через некоторое время (например, через 5 минут после выполнения чего-то в приложении). Я уже уведомляю пользователя, если приложение закрыто или находится в фоновом режиме. Но я хочу отображать UIAlertView во время работы приложения.Отображение UIAlertView через некоторое время

Я попытался dispatch_async следующим образом, но тревога хлопает навсегда:

[NSThread sleepForTimeInterval:minutes]; 
dispatch_async(dispatch_get_main_queue(), 
     ^{ 
     UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"title!" message:@"message!" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:nil]; 
     [alert show]; 
     [alert release]; 
     } 
     ); 

Кроме того, я прочитал, что нить умирает после 30 до 60 минут. Я хочу иметь возможность отображать оповещение после более чем 60 минут.

+0

Я заинтригован, где вы читали нити после 30-60 минут? –

+0

Я не могу найти, где я его читаю, но я считаю, что сделал. Я проверю его завтра и вернусь к вам. – Basel

ответ

12

Почему бы не использовать NSTimer, зачем вам использовать GCD в этом случае?

[NSTimer scheduledTimerWithTimeInterval:5*60 target:self selector:@selector(showAlert:) userInfo:nil repeats:NO]; 

Затем в том же классе, вы бы что-то вроде этого:

- (void) showAlert:(NSTimer *) timer { 
    UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"title!" 
                message:@"message!" 
                delegate:self    
              cancelButtonTitle:@"Cancel" 
              otherButtonTitles:nil]; 
    [alert show]; 
    [alert release]; 
} 

Кроме того, как отметил @PeyloW, вы можете использовать performSelector:withObject:afterDelay: тоже:

UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"title!" 
               message:@"message!" 
               delegate:self    
             cancelButtonTitle:@"Cancel" 
             otherButtonTitles:nil]; 
[alert performSelector:@selector(show) withObject:nil afterDelay:5*60]; 
[alert release]; 

EDIT Теперь вы можете использовать API dispatch_after GCD:

double delayInSeconds = 5; 
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); 
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"title!" 
                 message:@"message" 
                 delegate:self 
               cancelButtonTitle:@"Cancel" 
               otherButtonTitles:nil]; 
    [alertView show]; 
    [alertView release]; //Obviously you should not call this if you're using ARC 
}); 
+0

Или просто используйте 'performSelector: withObject: afterDelay:', и вам также не нужно будет запускать таймер. Факт, что вы можете вызвать метод 'show' на' UIAlertView' и не нужно использовать второй метод. – PeyloW

+0

@PeyloW Хорошая точка, хотя вы можете столкнуться с условиями гонки с этим как (я думаю) 'performSelector: withObject: afterDelay:' фактически выполняет селектор на вторичном потоке. Кроме того, когда вы «освободите» его? Пул автозапуска может освободить объект 'UIAlertView', прежде чем он сможет выполнить селектор' show'. Я думаю, что в этом случае стоит использовать «NSTimer». –

+3

'performSelector: withObject: afterDelay:' всегда будет выполнять селектор в текущем потоке, а объект сохраняется текущим циклом цикла до тех пор, пока он не будет выполнен (или отменен). На практике таймер создается неявно. API был бы совершенно бесполезен и не соответствовал бы правилам управления памятью Cocoa в противном случае. Так что, если ваши страхи необоснованны. – PeyloW

0

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

Here - учебник.

Смежные вопросы