IOS中带有完成块的后台任务 [英] Background task with Completion block in IOS

查看:76
本文介绍了IOS中带有完成块的后台任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在IOS中进行一些数据库操作.基本上,我想在后台线程中执行此操作.我尝试使用 GCD .但是对我来说,问题是我希望在此过程完成后从中获取一些价值.说在将一个项目插入数据库之前,我检查该项目是否已经存在.请参见下面的代码

I am doing some database operations in IOS. Basically I want to do this in a background thread. I tried using GCD. But the issue for me is I want to get some values from this process after it is finished. Say before inserting an item to database I check whether the item already exists. Please see code below

__block Boolean isExisting = false;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
                                             (unsigned long)NULL), ^(void) {
        NSString *path = [SqliteManager initDatabase];
        if(sqlite3_open([path UTF8String], &database) == SQLITE_OK)
        {
            NSString *query = [NSString stringWithFormat:@"select count (campaignId) from POTC where Id='%@' and taskid='%@' and pocId='%@' and userId='%@'",[submission.campaignId  stringRepresentation],[submission.taskId stringRepresentation],[submission.pocId stringRepresentation],[[UUID UUIDWithString:submission.userId] stringRepresentation]];
            const char *sql = [query cStringUsingEncoding:NSASCIIStringEncoding];
            sqlite3_stmt *selectStatement;
            if (sqlite3_prepare_v2(database, sql, -1, &selectStatement, NULL) == SQLITE_OK)
            {
                while (sqlite3_step(selectStatement) == SQLITE_ROW)
                {
                    if (sqlite3_column_int(selectStatement, 0) >0)
                    {
                        isExisting = true;
                        break;
                    }
                }
                sqlite3_finalize(selectStatement);
            }
            sqlite3_close(database);
        }
        return isExisting;
    });

但是上面带有return语句的代码无法正常工作,因为dispatch-async期望使用一个空代码块.如何在IOS中实现相同的目的? IOS中是否有类似于动画完成块的内容?

But the above code with return statement wont work as dispatch-async is expecting a void code block. How can i achieve the same in IOS? Is there something similar to animation completion block in IOS?

推荐答案

该块必须具有void的返回类型,因为在异步块中无处可返回该值.

The block has to have a return type of void because there is nowhere to return the value to in an asynchronous block.

变量isExisting是合格的__block,这意味着只要将块分配给它,就将其设置.不幸的是,一旦退出范围,您的主线程将无法访问它.谨慎执行此操作是让您的块调用另一个方法(或函数或块),该方法设置一个您知道在异步块完成后仍将存在的变量或属性.

The variable isExisting is qualified __block which means it will be set whenever the block assigns to it. Unfortunately, your main thread won't have access to it once it has exited the scope. The wary to do this is for your block to call another method (or function, or block) that sets a variable or property that you know will still be around when the asynchronous block has finished.

例如您可以在应用程序委托上有一个在完成时调用的方法.

e.g. you could have a method on the app delegate to invoke on completion.

// in your appDelegate implementation

-(void) updateUIAfterDatabaseUpdate: (bool) isExisting
{
    if (isExisting)
    {
        // e.g. display an error
    }
    else
    {
        // successful update
    }
}

// The update code

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
                                             (unsigned long)NULL), ^(void) {
        bool isExisting = false;

        NSString *path = [SqliteManager initDatabase];
        if(sqlite3_open([path UTF8String], &database) == SQLITE_OK)
        {
            // Snipped for clarity
        }
        dispatch_async(dispatch_get_main_queue(), ^(void) {
            [appDelegate updateUIAfterDatabaseUpdate: isExisting] ;
        });
    });

主队列上的调度确保在主线程中调用该方法,以便可以进行UI更新.

The dispatch on the main queue ensures that the method is called in the main thread so it can do UI updates.

这篇关于IOS中带有完成块的后台任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆