2014-10-17 18 views
0

我有一個UIlertView問用戶他/她是否想在數據執行某些事情之前備份數據。我做了這樣的事情,如果捕捉用戶點擊Yes(是):UIAlertView解除後執行任務

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 
    if (buttonIndex != alertView.cancelButtonIndex) 
     [self backupData]; 

    [self doSomethingWithData]; 
} 

但是,當用戶退出UIAlertView用戶界面將凍結,直到backupDatadoSomethingWithData方法完成。我認爲在後臺執行這些方法是不可接受的,因爲完成後必須啓動doSomethingWithData。 如何完全解除UIAlertView,然後啓動backupDatadoSomethingWithData方法?

+0

在後臺執行長時間運行的操作。 – rmaddy 2014-10-17 23:04:56

回答

2

因此,解決方案是eas y:

不想凍結UI --->使用背景與調度程序執行;

想要備份後執行某事 --->通過塊完成。

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 
{ 
    if (buttonIndex != alertView.cancelButtonIndex){ 
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^
     { 
      __weak typeof (self) weakSelf = self; 
      [self backupDataWithCompletion:^(NSData *data) { 
       [weakSelf doSomethingWithData:data]; 
      }]; 
     }); 

    } 
} 

- (void)backupDataWithCompletion:(void (^)(NSData *))completionBlock 
{ 
    NSData *data = //Do something 

    completionBlock(data); 
} 

或者另一種解決方案(那麼優雅)是插入在串行隊列不主線程上工作的任務:

因此,init這個隊列在init方法:

_queue = dispatch_queue_create("backupQueue", DISPATCH_QUEUE_SERIAL); 

隊列是一個屬性或VAR dispatch_queue_t queue; 然後:

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 
{ 
    if (buttonIndex != alertView.cancelButtonIndex){ 

     dispatch_async(queue,^
     { 
      [self backupData]; 
     }); 

     dispatch_async(queue,^
     { 
      [self doSomethingWithData]; 
     }); 

    } 
} 
+0

爲什麼你使用'weakSelf'作爲第二種方法,而不僅僅是'self'? – Hadu 2014-10-17 23:23:37

+0

爲了避免保留週期 – 2014-10-17 23:24:15

+0

第一種方法不適合我。 'doSomethingWithData'方法沒有被調用。 – Hadu 2014-10-17 23:45:34

0

只需在後臺執行這些方法。你很可能在主線程上做了一些沉重的事情,阻塞了用戶界面。

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^
    { 
     //code in background 
    }); 
} 

或者,也可以在後臺運行的一種方法,並且當第一個完下面使用代碼調用主線程上第二個。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^
{ 
    // do your background tasks here 
    [self doSomethingInBackground]; 

    // when that method finishes you can run whatever you need to on the main thread 
    dispatch_async(dispatch_get_main_queue(),^
    { 
     [self doSomethingInMainThread]; 
    }); 
}); 
+0

當在後臺運行[self doSomethingInBackground]時,爲什麼應用程序會等到它完成後才轉到[self doSomethingInMainThread]? – Hadu 2014-10-17 23:18:56

0

你也可以不喜歡它:

[self performSelector:@selector(doSomethingWithData) withObject:nil afterDelay:.1]; 
在您的變種

它會在主線程中調用。

OR

你也可以使用下面的代碼將其移動到後臺線程

[self performSelectorInBackground:@selector(doSomethingWithData) withObject:nil]; 

OR

你可以使用很多的建議與調度,結果將是一樣的...