解雇UIAlertView后执行任务

时间:2014-10-17 23:04:11

标签: ios uialertview

我有一个UIlertView询问用户他/她是否想要在执行数据之前备份数据。如果用户点击是,我做了类似这样的事情:

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

    [self doSomethingWithData];
}

但是当用户解除UIAlertView时,用户界面会冻结,直到backupDatadoSomethingWithData方法完成。我认为在后台执行这些方法是不可接受的,因为doSomethingWithData必须在backupData完成时启动。 如何完全解除UIAlertView,然后启动backupDatadoSomethingWithData方法?

3 个答案:

答案 0 :(得分:2)

所以,解决方案很简单:

不想冻结用户界面 ---> 使用后台执行调度程序;

希望在备份后执行某些操作 ---> 传递阻止以完成。

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

或者另一个解决方案(不那么优雅)是将任务插入到主线程不起作用的SERIAL QUEUE中:

因此,在init方法中初始化此队列:

_queue = dispatch_queue_create("backupQueue", DISPATCH_QUEUE_SERIAL);

queue是属性或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];
        });

    }
}

答案 1 :(得分:0)

只需在后台执行这些方法即可。你最有可能在主线程上做一些沉重的事情,阻止UI。

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

答案 2 :(得分:0)

你也可以这样做:

[self performSelector:@selector(doSomethingWithData) withObject:nil afterDelay:.1];

在您的变体中,它将在主线程中调用。

您还可以使用以下代码将其移至后台主题

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

你可以在调度中使用大量的建议,结果将是相同的......