ios - sqlite3_prepare_v2 崩溃 - 已经在运行之前的查询

标签 ios sqlite grand-central-dispatch

我编写了一个在 viewWillAppear 上触发的查询。通过快速导航返回到该屏幕会导致 sqlite3_prepare_v2 崩溃。
我假设崩溃是由于之前的查询未完成。
我正在使用 dispatch_async 调用数据库操作,因为我首先更新远程数据,然后将其保存在数据库中。
代码如下所示:

dispatch_queue_t myQueue = dispatch_queue_create("My Queue",NULL);

                 dispatch_async(myQueue, ^{
                    [self parseActivityResponse:data];  // Sqlite operation here
                     dispatch_async(dispatch_get_main_queue(), ^{
                         // Update the UI
                         if(loaderImageview)
                            [loaderImageview removeFromSuperview];
                         [tableActivities reloadData];

                     });
                 }); 

查询如下:

- (NSMutableArray*)GetAllInvitations:(NSString*)ActivityId
{
    NSMutableArray *arrInvitations = [[NSMutableArray alloc]init];

    sqlite3_stmt *statement = nil;

    @try {
        const char *sql = "SELECT * FROM Invitation where ActivityId = ?";

        if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK) {

            sqlite3_bind_text(statement, 1, [ActivityId UTF8String], -1, SQLITE_TRANSIENT);
            while (sqlite3_step(statement) == SQLITE_ROW) {

                char *dbString;

                Invitation *invitation = [[Invitation alloc]init];

                dbString = (char *)sqlite3_column_text(statement, 0);
                NSString *Id = (dbString) ? [NSString stringWithUTF8String:dbString] : @"";
                [invitation setId:Id];

                dbString = (char *)sqlite3_column_text(statement, 1);
                NSString *childName = (dbString) ? [NSString stringWithUTF8String:dbString] : @"";
                [invitation setChildName:childName];

                dbString = (char *)sqlite3_column_text(statement, 2);
                NSString *response = (dbString) ? [NSString stringWithUTF8String:dbString] : @"";
                [invitation setResponse:response];

                dbString = (char *)sqlite3_column_text(statement, 3);
                NSString *invitationId = (dbString) ? [NSString stringWithUTF8String:dbString] : @"";
                [invitation setInvitationId:invitationId];

                dbString = (char *)sqlite3_column_text(statement, 4);
                NSString *isCoGaurdian = (dbString) ? [NSString stringWithUTF8String:dbString] : @"";
                [invitation setIsCoGaurdian:isCoGaurdian];

                dbString = (char *)sqlite3_column_text(statement, 5);
                NSString *activityId = (dbString) ? [NSString stringWithUTF8String:dbString] : @"";
                [invitation setActivityId:activityId];

                dbString = (char *)sqlite3_column_text(statement, 6);
                NSString *picture = (dbString) ? [NSString stringWithUTF8String:dbString] : @"";
                [invitation setPicture:picture];

                dbString = (char *)sqlite3_column_text(statement, 7);
                NSString *invitationUserId = (dbString) ? [NSString stringWithUTF8String:dbString] : @"";
                [invitation setInvitedUserId:invitationUserId];

                dbString = (char *)sqlite3_column_text(statement, 8);
                NSString *roleId = (dbString) ? [NSString stringWithUTF8String:dbString] : @"";
                [invitation setRoleId:roleId];

                dbString = (char *)sqlite3_column_text(statement, 9);
                NSString *status = (dbString) ? [NSString stringWithUTF8String:dbString] : @"";
                [invitation setStatus:status];

                [arrInvitations addObject:invitation];
            }
        }
        else
        {
            NSLog(@"Failed to create table: %s", sqlite3_errmsg(database));
        }


    }
    @catch (NSException *exception) {

        NSLog(@"Error in GetAllInvitations : %@", exception.description);
    }
    @finally {

        sqlite3_finalize(statement);
    }

    return arrInvitations;
}  


- (NSMutableArray*)GetAllActivities{

    NSMutableArray *arrProjects = [[NSMutableArray alloc]init];

    sqlite3_stmt *statement = nil;

    @try {
        const char *sql = "SELECT * FROM Activity";

        if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK) {
            NSLog(@"success");
            while (sqlite3_step(statement) == SQLITE_ROW) {

                .........

                activity.arrInvitations = [self GetAllInvitations:activityId];

                [arrProjects addObject:activity];
            }
        }
        else
        {
            NSLog(@"Prepare-error #%i: %s", sqlite3_prepare_v2(database, sql, -1, &statement, NULL), sqlite3_errmsg(database));
        }
    }
    @catch (NSException *exception) {

        NSLog(@"Error in GetAllActivities : %@", exception.description);
    }
    @finally {

        sqlite3_finalize(statement);
    }

    return arrProjects;
}

我正在从 viewWillAppear 调用 GetAllActivities :

-(void) viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self reloadData];
}

-(void)reloadData
{
    [self getRemoteActivities:^(BOOL finished) {
        if(finished){
            if([TGProjectHandler hasExistingSession])
            {
                [self getActivities];

            }
            else
                [self login];   
        }
    }];
}

您的想法和解决方案?

最佳答案

创建一个串行队列:

dispatch_queue_t myQueue = dispatch_queue_create("My Queue", DISPATCH_QUEUE_SERIAL);

并且应该管理对数据库的顺序访问。

关于ios - sqlite3_prepare_v2 崩溃 - 已经在运行之前的查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31449643/

相关文章:

ios - Realm 使用 Objective-C 添加对象

ios - objective-C 。您的第一个 SKScene 是如何初始化的?

java - android中正确的sql UNION是什么?

ios - GCD 创建的线程数?

ios - 核心数据和 GCD : Passing the correct managed object context to custom NSManagedObjects

ios - 在 Swift 编程语言中隐藏文本字段的键盘

ios - skscene 中的 skscene

sqlite - ionic 2 sqlite在android上运行:无法读取未定义的属性executeSql

javascript - 如何在 HTML5 中访问 CSV 平面文件?

macos - 在 Linux 中使用大中央调度