在iOS中的sqlite3数据库上一次管理多个查询

时间:2014-01-21 06:58:06

标签: ios sqlite

我在iOS的sqlite3数据库中创建了两个表(vcards,viewdownloads)。在我的应用程序开始时,我开始使用后台进程将我的地址簿联系人插入到“vcards”表中的sqlite3数据库。

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    [self setNotificationForReachability];
    dispatch_queue_t loadQueue = dispatch_queue_create("Image loader", NULL);
    dispatch_async(loadQueue, ^{
        // Your code to run in the background here

        GVDBManager *objDB = [GVDBManager getSharedInstance];
        [objDB getContactsFromAddBook];
        [objDB syncPhoneBookWithVcardsTable];
    });
}
in the middle of this process of inserting contacts into "vcards" table, I have called the another background process to update some values using update query in same "vcards" table

在此过程完成后,Iam再次呼叫一个后台进程,将一些联系人插入“viewdownloads”表并使用UI显示联系人。  我的问题:  1.单击一个按钮,从数据库中读取联系人,这需要一些时间加载到阵列中(目标读取800个联系人)。我使用后台进程来做到这一点。  2.每次打开数据库并在使用后台进程插入和更新表时关闭它。这会导致我的应用程序崩溃,这是我面临的主要问题。  可以清楚地解释如何在同一个数据库上处理多个动作(插入,更新和搜索)。 在此先感谢。

1 个答案:

答案 0 :(得分:0)

1)你确定你的方法不需要在主线程上工作吗?也许某些指令需要它。

2)检测特定的exeption(或EXC_BAD_ACCESS)。我建议你启用所有断点。见下图:

enter image description here

3)这里主要用于打开查询和用sqlite关闭db的函数。我没有任何问题地使用这些东西

打开数据库连接的示例函数

- (NSError *) openDatabase {

    NSError *error = nil;

        sqlite3* db = self.db; // temp ref

    const char *dbpath = NULL;
        dbpath = [self.databaseName UTF8String]; // disk-based db

    // DB opening
    int result = sqlite3_open(dbpath, &db);
    if (result != SQLITE_OK) {
        // const char *errorMsg = sqlite3_errmsg(db);
        // ....
    }else
        self.db = db;

    return error;
}

关闭数据库连接的示例函数

- (NSError *) closeDatabase {

    NSError *error = nil;

    if (self.db != nil) {
        if (sqlite3_close(self.db) != SQLITE_OK){
            // const char *errorMsg = sqlite3_errmsg(self.db);
            // ...
        }           
        self.db = nil;
    }

    return error;
}

使用PDO查询数据库的示例函数(非SELECT子句)

- (NSError *)doPDOQuery:(NSString *)sql withParams:(NSArray *)params {

    //NSError *closeError = nil;
    __block NSError *errorQuery = nil;

    dispatch_sync(self.fetchQueue, ^{

        NSError *openError = nil;

        //Check if database is open and ready.
        if (self.db == nil) {
            openError = [self openDatabase];
        }

        if (openError == nil) {
            sqlite3_stmt *statement;
            const char *query = [sql UTF8String];
            sqlite3_prepare_v2(self.db, query, -1, &statement, NULL);

            // BINDING
            int count =0;
            for (id param in params ) {
                count++;
                if ([param isKindOfClass:[NSString class]] )
                    sqlite3_bind_text(statement, count, [param UTF8String], -1, SQLITE_TRANSIENT);
                if ([param isKindOfClass:[NSNumber class]] ) {

                    const char* paramObjType = [param objCType];

                    if (!strcmp(paramObjType, @encode(float))) // f
                        sqlite3_bind_double(statement, count, [param doubleValue]);
                    else if (!strcmp(paramObjType, @encode(double))) // d
                        sqlite3_bind_double(statement, count, [param doubleValue]);
                    else if (!strcmp(paramObjType, @encode(int))) // i
                        sqlite3_bind_int(statement, count, [param intValue]);
                    else if (!strcmp(paramObjType, @encode(unsigned int))) // I
                        sqlite3_bind_int(statement, count, [param unsignedIntValue]);
                    else if (!strcmp(paramObjType, @encode(char))) // c (eg: 1,0)
                        sqlite3_bind_int(statement, count, [param intValue]);
                    else if (!strcmp(paramObjType, @encode(long))) // q
                        sqlite3_bind_int64(statement, count, [param longLongValue]);
                    else if (!strcmp(paramObjType, @encode(unsigned long))) // Q
                        sqlite3_bind_int64(statement, count, [param unsignedLongLongValue]);
                    else
                        NSLog(@"SQLite binding - unknown NSNumber");
                }
            }

            int result = sqlite3_step(statement);
            if (result == SQLITE_ERROR ||
                result == SQLITE_CONSTRAINT) {
                // const char *errorMsg = sqlite3_errmsg(self.db);
                // ...
            }
            sqlite3_finalize(statement);

        }
        else
            errorQuery = openError;

    });

    return errorQuery;
}