Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios FMDB阻塞用户界面。但是为什么呢?对替代实施有何建议?_Ios_Multithreading_Fmdb - Fatal编程技术网

Ios FMDB阻塞用户界面。但是为什么呢?对替代实施有何建议?

Ios FMDB阻塞用户界面。但是为什么呢?对替代实施有何建议?,ios,multithreading,fmdb,Ios,Multithreading,Fmdb,我有一个应用程序,它使用FMDB并在应用程序启动时执行更新(仅一次)。更新相当繁重,需要12-20秒来处理。我使用FMDatabaseQueue处理基于单例类的事务 ==========DB.h==================== @interface DB : NSObject{ FMDatabaseQueue *dbqueue; NSArray *queriesCreateSchema; NSString *dbFullPath; } @property (no

我有一个应用程序,它使用FMDB并在应用程序启动时执行更新(仅一次)。更新相当繁重,需要12-20秒来处理。我使用FMDatabaseQueue处理基于单例类的事务

==========DB.h====================

@interface DB : NSObject{
    FMDatabaseQueue *dbqueue;
    NSArray *queriesCreateSchema;
    NSString *dbFullPath;
}

@property (nonatomic, strong) FMDatabaseQueue *dbqueue;
- (id)initWithFullPath: (NSString*)fullPath {
    if (self = [super init]) {

        dbFullPath = fullPath;

        //Opening/Creating the serial queue
        dbqueue = [FMDatabaseQueue databaseQueueWithPath:dbFullPath];
        if (dbqueue == nil){
            return nil;
        }

        queriesCreateSchema = [NSArray arrayWithObjects:DBQUERY_ENABLE_FOREIGN_KEYS,
                               DBQUERY_CREATE_DB,
                               DBQUERY_CREATE_USERS,
                               DBQUERY_CREATE_BOOKS,
                               DBQUERY_INDEX_BOOKS,
                               DBQUERY_CREATE_BOOKUSER,
                               DBQUERY_CREATE_PAGES,
                               DBQUERY_CREATE_PAGEUSER,
                               DBQUERY_CREATE_TAGS,
                               DBQUERY_CREATE_TAGBOOK,
                               DBQUERY_CREATE_CATEGORIES,
                               DBQUERY_CREATE_CATBOOK,
                               nil];
    }
    return self;
}
@interface DBManager : NSObject <CommsManagerDelegate> {
    __weak id <DBMDelegate>  delegate;
    DB *database;
    NSString *dbFullPath;
}


@property (nonatomic, weak) id <DBMDelegate> delegate;
@property (nonatomic, strong) DB *database;
@property (nonatomic, strong) NSString *dbFullPath;
-(BOOL) parseMetaDataDict: (NSDictionary*) serverDict {

    /// Getting the lists of books from the Server's JSON dictionary
    NSDictionary *dictAllBooks = [serverDict objectForKey:@"Books"];

    int bookNum=0;
    int totalBooks = [[dictAllBooks valueForKey:@"Book"] count];

    // Updates the UI
    [delegate dbmNumberOfBooksProcessedByDB:totalBooks];

    /// Browsing it book by book
    for (id serverDictBook in [dictAllBooks valueForKey:@"Book"]){
        bookNum++;

        /// Trimming book from the server and placing it into the local book dictionary
        BookDict *bookDict = [[BookDict alloc]initWithServerDict:serverDictBook];

        __block BOOL isError = NO;

        /// Sending the queries into the serial queue
        [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
            /// Inserting book into the BOOKS table
            if(![db executeUpdate:DBUPDATE_INSERT_BOOK withParameterDictionary:bookDict.dictionary])
            {
                isError = YES;
                DDLogWarn(@"%@", [db lastErrorMessage]);
                *rollback = YES;
                return;      // Carefull - It returns from the transaction, not the function
            }
        }];

        if (isError){
            return NO;
        }

        __block NSString *bookID;

        /// Getting the bookID automatically generated by the DB
        NSString *query = [NSString stringWithFormat:@"SELECT bookID FROM BOOKS where isbn = '%@'", [bookDict.dictionary valueForKey:@"isbn"]];
        [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
            FMResultSet *result = [db executeQuery:query];
            if([result next])
            {
                int num = [result intForColumnIndex:0];
                bookID = [NSString stringWithFormat:@"%d", num];
            }
            else{
                isError = YES;
                DDLogWarn(@"%@", [db lastErrorMessage]);
                *rollback = YES;
                return;      // Carefull - It returns from the transaction, not the function
            }
        }];

        if (isError){
            return NO;
        }


        int numPages = [[serverDictBook objectForKey:@"numberOfPages"] intValue];

        /// Browsing the book page by page
        ///VCC Today probably replace by 0
        for (int i=1; i<=numPages; i++)
        {
            PageDict *pageDict = [[PageDict alloc]initWithPage:i andBookID:bookID ofServerDict:serverDictBook];

            __block BOOL isError = NO;

            /// Sending the queries into the serial queue
            [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
                /// Inserting page into the PAGES table
                if(![db executeUpdate:DBUPDATE_INSERT_PAGE withParameterDictionary:pageDict.dictionary])
                {
                    isError = YES;
                    DDLogWarn(@"%@", [db lastErrorMessage]);
                    *rollback = YES;
                    return;      // Carefull - It returns from the transaction, not the function
                }
            }];

            if (isError)
            return NO;
        }


        __block NSString *catID;

        /// Browsing the book categories one by one
        for (id serverCatDict in [serverDictBook valueForKey:@"categories"]){

            __block BOOL isError = NO;

            /// Sending the queries into the serial queue
            [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
                /// Inserting row into the CATEGORY table
                if(![db executeUpdate:DBUPDATE_INSERT_CATEGORY withParameterDictionary:serverCatDict])
                {
                    isError = YES;
                    DDLogWarn(@"%@", [db lastErrorMessage]);
                    *rollback = YES;
                    return;      // Carefull - It returns from the transaction, not the function
                }

                /// Getting the catID automatically generated by the DB
                NSString *query = [NSString stringWithFormat:@"SELECT catID FROM CATEGORIES where name = '%@'", [serverCatDict valueForKey:@"name"]];

                FMResultSet *result = [db executeQuery:query];
                if([result next])
                {
                  catID = [result stringForColumnIndex:0];
                }
                else{
                  isError = YES;
                  DDLogError(@"%@", [db lastErrorMessage]);
                  *rollback = YES;
                  return;      // Carefull - It returns from the transaction, not the function
                }

              CatBookDict *catBookDict = [[CatBookDict alloc] initWithCatID:catID andBookID:bookID];

              /// Inserting row into the CATBOOK table
              if(![db executeUpdate:DBUPDATE_INSERT_CATBOOK withParameterDictionary:catBookDict.dictionary])
              {
                isError = YES;
                DDLogError(@"%@", [db lastErrorMessage]);
                *rollback = YES;
                return;      // Carefull - It returns from the transaction, not the function
              }

          }];

          if (isError)
              return NO;

        }


//      /// Browsing the book categories one by one
//      for (id serverCatDict in [serverDictBook valueForKey:@"name"]){
//        
//          __block BOOL isError = NO;
//
//        CatBookDict *catBookDict = [[CatBookDict alloc] initWithCatID:[serverCatDict valueForKey:@"catID"]];
//
//          /// Sending the queries into the serial queue
//          [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
//                                  andBookID:bookID];
//              /// Inserting row into the CATBOOK table
//              if(![db executeUpdate:DBUPDATE_INSERT_CATBOOK withParameterDictionary:catBookDict.dictionary])
//              {
//                isError = YES;
//                DDLogVerbose(@"%@", [db lastErrorMessage]);
//                *rollback = YES;
//                return;      // Carefull - It returns from the transaction, not the function
//              }
//          }];
//                                      
//          if (isError)
//          return NO;
//
//      }
      [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
        FMResultSet *result = [db executeQuery:query];
        if([result next])
        {
          int num = [result intForColumnIndex:0];
          bookID = [NSString stringWithFormat:@"%d", num];
        }
        else{
          isError = YES;
          DDLogError(@"%@", [db lastErrorMessage]);
          *rollback = YES;
          return;      // Carefull - It returns from the transaction, not the function
        }
      }];

      if (isError){
        return NO;
      }



        /// Browsing the book tags one by one
        for (id serverTagDict in [serverDictBook valueForKey:@"tags"]){
//            TagDict *tagDict = [[TagDict alloc] initWithServerDict:serverTagDict[0]];
//            TagBookDict *tagBookDict = [[TagBookDict alloc] initWithTagID:[serverTagDict valueForKey:@"tagID"]
//                                                                andBookID:bookID];
            __block BOOL isError = NO;

            /// Sending the queries into the serial queue
            [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
                /// Inserting tag into the TAGS table
                if(![db executeUpdate:DBUPDATE_INSERT_TAG withParameterDictionary:serverTagDict])
                {
                    isError = YES;
                    DDLogError(@"%@", [db lastErrorMessage]);
                    *rollback = YES;
                    return;      // Carefull - It returns from the transaction, not the function
                }

//                /// Inserting the row into the TAGBOOK table
//                if(![db executeUpdate:DBUPDATE_INSERT_TAGBOOK withParameterDictionary:tagBookDict.dictionary])
//                {
//                    isError = YES;
//                    DDLogVerbose(@"%@", [db lastErrorMessage]);
//                    *rollback = YES;
//                    return;      // Carefull - It returns from the transaction, not the function
//                }

            }];

            if (isError)
                return NO;
        }

        // Updates the UI
        [delegate dbmBookProcessedByDB:bookNum];

    }

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    if (![defaults objectForKey:@"firstSynced"]){
        [defaults setObject:[NSDate date] forKey:@"firstSynced"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }

    return TRUE;
==================================

@interface DB : NSObject{
    FMDatabaseQueue *dbqueue;
    NSArray *queriesCreateSchema;
    NSString *dbFullPath;
}

@property (nonatomic, strong) FMDatabaseQueue *dbqueue;
- (id)initWithFullPath: (NSString*)fullPath {
    if (self = [super init]) {

        dbFullPath = fullPath;

        //Opening/Creating the serial queue
        dbqueue = [FMDatabaseQueue databaseQueueWithPath:dbFullPath];
        if (dbqueue == nil){
            return nil;
        }

        queriesCreateSchema = [NSArray arrayWithObjects:DBQUERY_ENABLE_FOREIGN_KEYS,
                               DBQUERY_CREATE_DB,
                               DBQUERY_CREATE_USERS,
                               DBQUERY_CREATE_BOOKS,
                               DBQUERY_INDEX_BOOKS,
                               DBQUERY_CREATE_BOOKUSER,
                               DBQUERY_CREATE_PAGES,
                               DBQUERY_CREATE_PAGEUSER,
                               DBQUERY_CREATE_TAGS,
                               DBQUERY_CREATE_TAGBOOK,
                               DBQUERY_CREATE_CATEGORIES,
                               DBQUERY_CREATE_CATBOOK,
                               nil];
    }
    return self;
}
@interface DBManager : NSObject <CommsManagerDelegate> {
    __weak id <DBMDelegate>  delegate;
    DB *database;
    NSString *dbFullPath;
}


@property (nonatomic, weak) id <DBMDelegate> delegate;
@property (nonatomic, strong) DB *database;
@property (nonatomic, strong) NSString *dbFullPath;
-(BOOL) parseMetaDataDict: (NSDictionary*) serverDict {

    /// Getting the lists of books from the Server's JSON dictionary
    NSDictionary *dictAllBooks = [serverDict objectForKey:@"Books"];

    int bookNum=0;
    int totalBooks = [[dictAllBooks valueForKey:@"Book"] count];

    // Updates the UI
    [delegate dbmNumberOfBooksProcessedByDB:totalBooks];

    /// Browsing it book by book
    for (id serverDictBook in [dictAllBooks valueForKey:@"Book"]){
        bookNum++;

        /// Trimming book from the server and placing it into the local book dictionary
        BookDict *bookDict = [[BookDict alloc]initWithServerDict:serverDictBook];

        __block BOOL isError = NO;

        /// Sending the queries into the serial queue
        [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
            /// Inserting book into the BOOKS table
            if(![db executeUpdate:DBUPDATE_INSERT_BOOK withParameterDictionary:bookDict.dictionary])
            {
                isError = YES;
                DDLogWarn(@"%@", [db lastErrorMessage]);
                *rollback = YES;
                return;      // Carefull - It returns from the transaction, not the function
            }
        }];

        if (isError){
            return NO;
        }

        __block NSString *bookID;

        /// Getting the bookID automatically generated by the DB
        NSString *query = [NSString stringWithFormat:@"SELECT bookID FROM BOOKS where isbn = '%@'", [bookDict.dictionary valueForKey:@"isbn"]];
        [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
            FMResultSet *result = [db executeQuery:query];
            if([result next])
            {
                int num = [result intForColumnIndex:0];
                bookID = [NSString stringWithFormat:@"%d", num];
            }
            else{
                isError = YES;
                DDLogWarn(@"%@", [db lastErrorMessage]);
                *rollback = YES;
                return;      // Carefull - It returns from the transaction, not the function
            }
        }];

        if (isError){
            return NO;
        }


        int numPages = [[serverDictBook objectForKey:@"numberOfPages"] intValue];

        /// Browsing the book page by page
        ///VCC Today probably replace by 0
        for (int i=1; i<=numPages; i++)
        {
            PageDict *pageDict = [[PageDict alloc]initWithPage:i andBookID:bookID ofServerDict:serverDictBook];

            __block BOOL isError = NO;

            /// Sending the queries into the serial queue
            [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
                /// Inserting page into the PAGES table
                if(![db executeUpdate:DBUPDATE_INSERT_PAGE withParameterDictionary:pageDict.dictionary])
                {
                    isError = YES;
                    DDLogWarn(@"%@", [db lastErrorMessage]);
                    *rollback = YES;
                    return;      // Carefull - It returns from the transaction, not the function
                }
            }];

            if (isError)
            return NO;
        }


        __block NSString *catID;

        /// Browsing the book categories one by one
        for (id serverCatDict in [serverDictBook valueForKey:@"categories"]){

            __block BOOL isError = NO;

            /// Sending the queries into the serial queue
            [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
                /// Inserting row into the CATEGORY table
                if(![db executeUpdate:DBUPDATE_INSERT_CATEGORY withParameterDictionary:serverCatDict])
                {
                    isError = YES;
                    DDLogWarn(@"%@", [db lastErrorMessage]);
                    *rollback = YES;
                    return;      // Carefull - It returns from the transaction, not the function
                }

                /// Getting the catID automatically generated by the DB
                NSString *query = [NSString stringWithFormat:@"SELECT catID FROM CATEGORIES where name = '%@'", [serverCatDict valueForKey:@"name"]];

                FMResultSet *result = [db executeQuery:query];
                if([result next])
                {
                  catID = [result stringForColumnIndex:0];
                }
                else{
                  isError = YES;
                  DDLogError(@"%@", [db lastErrorMessage]);
                  *rollback = YES;
                  return;      // Carefull - It returns from the transaction, not the function
                }

              CatBookDict *catBookDict = [[CatBookDict alloc] initWithCatID:catID andBookID:bookID];

              /// Inserting row into the CATBOOK table
              if(![db executeUpdate:DBUPDATE_INSERT_CATBOOK withParameterDictionary:catBookDict.dictionary])
              {
                isError = YES;
                DDLogError(@"%@", [db lastErrorMessage]);
                *rollback = YES;
                return;      // Carefull - It returns from the transaction, not the function
              }

          }];

          if (isError)
              return NO;

        }


//      /// Browsing the book categories one by one
//      for (id serverCatDict in [serverDictBook valueForKey:@"name"]){
//        
//          __block BOOL isError = NO;
//
//        CatBookDict *catBookDict = [[CatBookDict alloc] initWithCatID:[serverCatDict valueForKey:@"catID"]];
//
//          /// Sending the queries into the serial queue
//          [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
//                                  andBookID:bookID];
//              /// Inserting row into the CATBOOK table
//              if(![db executeUpdate:DBUPDATE_INSERT_CATBOOK withParameterDictionary:catBookDict.dictionary])
//              {
//                isError = YES;
//                DDLogVerbose(@"%@", [db lastErrorMessage]);
//                *rollback = YES;
//                return;      // Carefull - It returns from the transaction, not the function
//              }
//          }];
//                                      
//          if (isError)
//          return NO;
//
//      }
      [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
        FMResultSet *result = [db executeQuery:query];
        if([result next])
        {
          int num = [result intForColumnIndex:0];
          bookID = [NSString stringWithFormat:@"%d", num];
        }
        else{
          isError = YES;
          DDLogError(@"%@", [db lastErrorMessage]);
          *rollback = YES;
          return;      // Carefull - It returns from the transaction, not the function
        }
      }];

      if (isError){
        return NO;
      }



        /// Browsing the book tags one by one
        for (id serverTagDict in [serverDictBook valueForKey:@"tags"]){
//            TagDict *tagDict = [[TagDict alloc] initWithServerDict:serverTagDict[0]];
//            TagBookDict *tagBookDict = [[TagBookDict alloc] initWithTagID:[serverTagDict valueForKey:@"tagID"]
//                                                                andBookID:bookID];
            __block BOOL isError = NO;

            /// Sending the queries into the serial queue
            [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
                /// Inserting tag into the TAGS table
                if(![db executeUpdate:DBUPDATE_INSERT_TAG withParameterDictionary:serverTagDict])
                {
                    isError = YES;
                    DDLogError(@"%@", [db lastErrorMessage]);
                    *rollback = YES;
                    return;      // Carefull - It returns from the transaction, not the function
                }

//                /// Inserting the row into the TAGBOOK table
//                if(![db executeUpdate:DBUPDATE_INSERT_TAGBOOK withParameterDictionary:tagBookDict.dictionary])
//                {
//                    isError = YES;
//                    DDLogVerbose(@"%@", [db lastErrorMessage]);
//                    *rollback = YES;
//                    return;      // Carefull - It returns from the transaction, not the function
//                }

            }];

            if (isError)
                return NO;
        }

        // Updates the UI
        [delegate dbmBookProcessedByDB:bookNum];

    }

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    if (![defaults objectForKey:@"firstSynced"]){
        [defaults setObject:[NSDate date] forKey:@"firstSynced"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }

    return TRUE;
==========DB.m====================

@interface DB : NSObject{
    FMDatabaseQueue *dbqueue;
    NSArray *queriesCreateSchema;
    NSString *dbFullPath;
}

@property (nonatomic, strong) FMDatabaseQueue *dbqueue;
- (id)initWithFullPath: (NSString*)fullPath {
    if (self = [super init]) {

        dbFullPath = fullPath;

        //Opening/Creating the serial queue
        dbqueue = [FMDatabaseQueue databaseQueueWithPath:dbFullPath];
        if (dbqueue == nil){
            return nil;
        }

        queriesCreateSchema = [NSArray arrayWithObjects:DBQUERY_ENABLE_FOREIGN_KEYS,
                               DBQUERY_CREATE_DB,
                               DBQUERY_CREATE_USERS,
                               DBQUERY_CREATE_BOOKS,
                               DBQUERY_INDEX_BOOKS,
                               DBQUERY_CREATE_BOOKUSER,
                               DBQUERY_CREATE_PAGES,
                               DBQUERY_CREATE_PAGEUSER,
                               DBQUERY_CREATE_TAGS,
                               DBQUERY_CREATE_TAGBOOK,
                               DBQUERY_CREATE_CATEGORIES,
                               DBQUERY_CREATE_CATBOOK,
                               nil];
    }
    return self;
}
@interface DBManager : NSObject <CommsManagerDelegate> {
    __weak id <DBMDelegate>  delegate;
    DB *database;
    NSString *dbFullPath;
}


@property (nonatomic, weak) id <DBMDelegate> delegate;
@property (nonatomic, strong) DB *database;
@property (nonatomic, strong) NSString *dbFullPath;
-(BOOL) parseMetaDataDict: (NSDictionary*) serverDict {

    /// Getting the lists of books from the Server's JSON dictionary
    NSDictionary *dictAllBooks = [serverDict objectForKey:@"Books"];

    int bookNum=0;
    int totalBooks = [[dictAllBooks valueForKey:@"Book"] count];

    // Updates the UI
    [delegate dbmNumberOfBooksProcessedByDB:totalBooks];

    /// Browsing it book by book
    for (id serverDictBook in [dictAllBooks valueForKey:@"Book"]){
        bookNum++;

        /// Trimming book from the server and placing it into the local book dictionary
        BookDict *bookDict = [[BookDict alloc]initWithServerDict:serverDictBook];

        __block BOOL isError = NO;

        /// Sending the queries into the serial queue
        [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
            /// Inserting book into the BOOKS table
            if(![db executeUpdate:DBUPDATE_INSERT_BOOK withParameterDictionary:bookDict.dictionary])
            {
                isError = YES;
                DDLogWarn(@"%@", [db lastErrorMessage]);
                *rollback = YES;
                return;      // Carefull - It returns from the transaction, not the function
            }
        }];

        if (isError){
            return NO;
        }

        __block NSString *bookID;

        /// Getting the bookID automatically generated by the DB
        NSString *query = [NSString stringWithFormat:@"SELECT bookID FROM BOOKS where isbn = '%@'", [bookDict.dictionary valueForKey:@"isbn"]];
        [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
            FMResultSet *result = [db executeQuery:query];
            if([result next])
            {
                int num = [result intForColumnIndex:0];
                bookID = [NSString stringWithFormat:@"%d", num];
            }
            else{
                isError = YES;
                DDLogWarn(@"%@", [db lastErrorMessage]);
                *rollback = YES;
                return;      // Carefull - It returns from the transaction, not the function
            }
        }];

        if (isError){
            return NO;
        }


        int numPages = [[serverDictBook objectForKey:@"numberOfPages"] intValue];

        /// Browsing the book page by page
        ///VCC Today probably replace by 0
        for (int i=1; i<=numPages; i++)
        {
            PageDict *pageDict = [[PageDict alloc]initWithPage:i andBookID:bookID ofServerDict:serverDictBook];

            __block BOOL isError = NO;

            /// Sending the queries into the serial queue
            [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
                /// Inserting page into the PAGES table
                if(![db executeUpdate:DBUPDATE_INSERT_PAGE withParameterDictionary:pageDict.dictionary])
                {
                    isError = YES;
                    DDLogWarn(@"%@", [db lastErrorMessage]);
                    *rollback = YES;
                    return;      // Carefull - It returns from the transaction, not the function
                }
            }];

            if (isError)
            return NO;
        }


        __block NSString *catID;

        /// Browsing the book categories one by one
        for (id serverCatDict in [serverDictBook valueForKey:@"categories"]){

            __block BOOL isError = NO;

            /// Sending the queries into the serial queue
            [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
                /// Inserting row into the CATEGORY table
                if(![db executeUpdate:DBUPDATE_INSERT_CATEGORY withParameterDictionary:serverCatDict])
                {
                    isError = YES;
                    DDLogWarn(@"%@", [db lastErrorMessage]);
                    *rollback = YES;
                    return;      // Carefull - It returns from the transaction, not the function
                }

                /// Getting the catID automatically generated by the DB
                NSString *query = [NSString stringWithFormat:@"SELECT catID FROM CATEGORIES where name = '%@'", [serverCatDict valueForKey:@"name"]];

                FMResultSet *result = [db executeQuery:query];
                if([result next])
                {
                  catID = [result stringForColumnIndex:0];
                }
                else{
                  isError = YES;
                  DDLogError(@"%@", [db lastErrorMessage]);
                  *rollback = YES;
                  return;      // Carefull - It returns from the transaction, not the function
                }

              CatBookDict *catBookDict = [[CatBookDict alloc] initWithCatID:catID andBookID:bookID];

              /// Inserting row into the CATBOOK table
              if(![db executeUpdate:DBUPDATE_INSERT_CATBOOK withParameterDictionary:catBookDict.dictionary])
              {
                isError = YES;
                DDLogError(@"%@", [db lastErrorMessage]);
                *rollback = YES;
                return;      // Carefull - It returns from the transaction, not the function
              }

          }];

          if (isError)
              return NO;

        }


//      /// Browsing the book categories one by one
//      for (id serverCatDict in [serverDictBook valueForKey:@"name"]){
//        
//          __block BOOL isError = NO;
//
//        CatBookDict *catBookDict = [[CatBookDict alloc] initWithCatID:[serverCatDict valueForKey:@"catID"]];
//
//          /// Sending the queries into the serial queue
//          [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
//                                  andBookID:bookID];
//              /// Inserting row into the CATBOOK table
//              if(![db executeUpdate:DBUPDATE_INSERT_CATBOOK withParameterDictionary:catBookDict.dictionary])
//              {
//                isError = YES;
//                DDLogVerbose(@"%@", [db lastErrorMessage]);
//                *rollback = YES;
//                return;      // Carefull - It returns from the transaction, not the function
//              }
//          }];
//                                      
//          if (isError)
//          return NO;
//
//      }
      [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
        FMResultSet *result = [db executeQuery:query];
        if([result next])
        {
          int num = [result intForColumnIndex:0];
          bookID = [NSString stringWithFormat:@"%d", num];
        }
        else{
          isError = YES;
          DDLogError(@"%@", [db lastErrorMessage]);
          *rollback = YES;
          return;      // Carefull - It returns from the transaction, not the function
        }
      }];

      if (isError){
        return NO;
      }



        /// Browsing the book tags one by one
        for (id serverTagDict in [serverDictBook valueForKey:@"tags"]){
//            TagDict *tagDict = [[TagDict alloc] initWithServerDict:serverTagDict[0]];
//            TagBookDict *tagBookDict = [[TagBookDict alloc] initWithTagID:[serverTagDict valueForKey:@"tagID"]
//                                                                andBookID:bookID];
            __block BOOL isError = NO;

            /// Sending the queries into the serial queue
            [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
                /// Inserting tag into the TAGS table
                if(![db executeUpdate:DBUPDATE_INSERT_TAG withParameterDictionary:serverTagDict])
                {
                    isError = YES;
                    DDLogError(@"%@", [db lastErrorMessage]);
                    *rollback = YES;
                    return;      // Carefull - It returns from the transaction, not the function
                }

//                /// Inserting the row into the TAGBOOK table
//                if(![db executeUpdate:DBUPDATE_INSERT_TAGBOOK withParameterDictionary:tagBookDict.dictionary])
//                {
//                    isError = YES;
//                    DDLogVerbose(@"%@", [db lastErrorMessage]);
//                    *rollback = YES;
//                    return;      // Carefull - It returns from the transaction, not the function
//                }

            }];

            if (isError)
                return NO;
        }

        // Updates the UI
        [delegate dbmBookProcessedByDB:bookNum];

    }

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    if (![defaults objectForKey:@"firstSynced"]){
        [defaults setObject:[NSDate date] forKey:@"firstSynced"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }

    return TRUE;
================================== =======DBManager.h====================

@interface DB : NSObject{
    FMDatabaseQueue *dbqueue;
    NSArray *queriesCreateSchema;
    NSString *dbFullPath;
}

@property (nonatomic, strong) FMDatabaseQueue *dbqueue;
- (id)initWithFullPath: (NSString*)fullPath {
    if (self = [super init]) {

        dbFullPath = fullPath;

        //Opening/Creating the serial queue
        dbqueue = [FMDatabaseQueue databaseQueueWithPath:dbFullPath];
        if (dbqueue == nil){
            return nil;
        }

        queriesCreateSchema = [NSArray arrayWithObjects:DBQUERY_ENABLE_FOREIGN_KEYS,
                               DBQUERY_CREATE_DB,
                               DBQUERY_CREATE_USERS,
                               DBQUERY_CREATE_BOOKS,
                               DBQUERY_INDEX_BOOKS,
                               DBQUERY_CREATE_BOOKUSER,
                               DBQUERY_CREATE_PAGES,
                               DBQUERY_CREATE_PAGEUSER,
                               DBQUERY_CREATE_TAGS,
                               DBQUERY_CREATE_TAGBOOK,
                               DBQUERY_CREATE_CATEGORIES,
                               DBQUERY_CREATE_CATBOOK,
                               nil];
    }
    return self;
}
@interface DBManager : NSObject <CommsManagerDelegate> {
    __weak id <DBMDelegate>  delegate;
    DB *database;
    NSString *dbFullPath;
}


@property (nonatomic, weak) id <DBMDelegate> delegate;
@property (nonatomic, strong) DB *database;
@property (nonatomic, strong) NSString *dbFullPath;
-(BOOL) parseMetaDataDict: (NSDictionary*) serverDict {

    /// Getting the lists of books from the Server's JSON dictionary
    NSDictionary *dictAllBooks = [serverDict objectForKey:@"Books"];

    int bookNum=0;
    int totalBooks = [[dictAllBooks valueForKey:@"Book"] count];

    // Updates the UI
    [delegate dbmNumberOfBooksProcessedByDB:totalBooks];

    /// Browsing it book by book
    for (id serverDictBook in [dictAllBooks valueForKey:@"Book"]){
        bookNum++;

        /// Trimming book from the server and placing it into the local book dictionary
        BookDict *bookDict = [[BookDict alloc]initWithServerDict:serverDictBook];

        __block BOOL isError = NO;

        /// Sending the queries into the serial queue
        [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
            /// Inserting book into the BOOKS table
            if(![db executeUpdate:DBUPDATE_INSERT_BOOK withParameterDictionary:bookDict.dictionary])
            {
                isError = YES;
                DDLogWarn(@"%@", [db lastErrorMessage]);
                *rollback = YES;
                return;      // Carefull - It returns from the transaction, not the function
            }
        }];

        if (isError){
            return NO;
        }

        __block NSString *bookID;

        /// Getting the bookID automatically generated by the DB
        NSString *query = [NSString stringWithFormat:@"SELECT bookID FROM BOOKS where isbn = '%@'", [bookDict.dictionary valueForKey:@"isbn"]];
        [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
            FMResultSet *result = [db executeQuery:query];
            if([result next])
            {
                int num = [result intForColumnIndex:0];
                bookID = [NSString stringWithFormat:@"%d", num];
            }
            else{
                isError = YES;
                DDLogWarn(@"%@", [db lastErrorMessage]);
                *rollback = YES;
                return;      // Carefull - It returns from the transaction, not the function
            }
        }];

        if (isError){
            return NO;
        }


        int numPages = [[serverDictBook objectForKey:@"numberOfPages"] intValue];

        /// Browsing the book page by page
        ///VCC Today probably replace by 0
        for (int i=1; i<=numPages; i++)
        {
            PageDict *pageDict = [[PageDict alloc]initWithPage:i andBookID:bookID ofServerDict:serverDictBook];

            __block BOOL isError = NO;

            /// Sending the queries into the serial queue
            [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
                /// Inserting page into the PAGES table
                if(![db executeUpdate:DBUPDATE_INSERT_PAGE withParameterDictionary:pageDict.dictionary])
                {
                    isError = YES;
                    DDLogWarn(@"%@", [db lastErrorMessage]);
                    *rollback = YES;
                    return;      // Carefull - It returns from the transaction, not the function
                }
            }];

            if (isError)
            return NO;
        }


        __block NSString *catID;

        /// Browsing the book categories one by one
        for (id serverCatDict in [serverDictBook valueForKey:@"categories"]){

            __block BOOL isError = NO;

            /// Sending the queries into the serial queue
            [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
                /// Inserting row into the CATEGORY table
                if(![db executeUpdate:DBUPDATE_INSERT_CATEGORY withParameterDictionary:serverCatDict])
                {
                    isError = YES;
                    DDLogWarn(@"%@", [db lastErrorMessage]);
                    *rollback = YES;
                    return;      // Carefull - It returns from the transaction, not the function
                }

                /// Getting the catID automatically generated by the DB
                NSString *query = [NSString stringWithFormat:@"SELECT catID FROM CATEGORIES where name = '%@'", [serverCatDict valueForKey:@"name"]];

                FMResultSet *result = [db executeQuery:query];
                if([result next])
                {
                  catID = [result stringForColumnIndex:0];
                }
                else{
                  isError = YES;
                  DDLogError(@"%@", [db lastErrorMessage]);
                  *rollback = YES;
                  return;      // Carefull - It returns from the transaction, not the function
                }

              CatBookDict *catBookDict = [[CatBookDict alloc] initWithCatID:catID andBookID:bookID];

              /// Inserting row into the CATBOOK table
              if(![db executeUpdate:DBUPDATE_INSERT_CATBOOK withParameterDictionary:catBookDict.dictionary])
              {
                isError = YES;
                DDLogError(@"%@", [db lastErrorMessage]);
                *rollback = YES;
                return;      // Carefull - It returns from the transaction, not the function
              }

          }];

          if (isError)
              return NO;

        }


//      /// Browsing the book categories one by one
//      for (id serverCatDict in [serverDictBook valueForKey:@"name"]){
//        
//          __block BOOL isError = NO;
//
//        CatBookDict *catBookDict = [[CatBookDict alloc] initWithCatID:[serverCatDict valueForKey:@"catID"]];
//
//          /// Sending the queries into the serial queue
//          [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
//                                  andBookID:bookID];
//              /// Inserting row into the CATBOOK table
//              if(![db executeUpdate:DBUPDATE_INSERT_CATBOOK withParameterDictionary:catBookDict.dictionary])
//              {
//                isError = YES;
//                DDLogVerbose(@"%@", [db lastErrorMessage]);
//                *rollback = YES;
//                return;      // Carefull - It returns from the transaction, not the function
//              }
//          }];
//                                      
//          if (isError)
//          return NO;
//
//      }
      [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
        FMResultSet *result = [db executeQuery:query];
        if([result next])
        {
          int num = [result intForColumnIndex:0];
          bookID = [NSString stringWithFormat:@"%d", num];
        }
        else{
          isError = YES;
          DDLogError(@"%@", [db lastErrorMessage]);
          *rollback = YES;
          return;      // Carefull - It returns from the transaction, not the function
        }
      }];

      if (isError){
        return NO;
      }



        /// Browsing the book tags one by one
        for (id serverTagDict in [serverDictBook valueForKey:@"tags"]){
//            TagDict *tagDict = [[TagDict alloc] initWithServerDict:serverTagDict[0]];
//            TagBookDict *tagBookDict = [[TagBookDict alloc] initWithTagID:[serverTagDict valueForKey:@"tagID"]
//                                                                andBookID:bookID];
            __block BOOL isError = NO;

            /// Sending the queries into the serial queue
            [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
                /// Inserting tag into the TAGS table
                if(![db executeUpdate:DBUPDATE_INSERT_TAG withParameterDictionary:serverTagDict])
                {
                    isError = YES;
                    DDLogError(@"%@", [db lastErrorMessage]);
                    *rollback = YES;
                    return;      // Carefull - It returns from the transaction, not the function
                }

//                /// Inserting the row into the TAGBOOK table
//                if(![db executeUpdate:DBUPDATE_INSERT_TAGBOOK withParameterDictionary:tagBookDict.dictionary])
//                {
//                    isError = YES;
//                    DDLogVerbose(@"%@", [db lastErrorMessage]);
//                    *rollback = YES;
//                    return;      // Carefull - It returns from the transaction, not the function
//                }

            }];

            if (isError)
                return NO;
        }

        // Updates the UI
        [delegate dbmBookProcessedByDB:bookNum];

    }

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    if (![defaults objectForKey:@"firstSynced"]){
        [defaults setObject:[NSDate date] forKey:@"firstSynced"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }

    return TRUE;
=========================================

@interface DB : NSObject{
    FMDatabaseQueue *dbqueue;
    NSArray *queriesCreateSchema;
    NSString *dbFullPath;
}

@property (nonatomic, strong) FMDatabaseQueue *dbqueue;
- (id)initWithFullPath: (NSString*)fullPath {
    if (self = [super init]) {

        dbFullPath = fullPath;

        //Opening/Creating the serial queue
        dbqueue = [FMDatabaseQueue databaseQueueWithPath:dbFullPath];
        if (dbqueue == nil){
            return nil;
        }

        queriesCreateSchema = [NSArray arrayWithObjects:DBQUERY_ENABLE_FOREIGN_KEYS,
                               DBQUERY_CREATE_DB,
                               DBQUERY_CREATE_USERS,
                               DBQUERY_CREATE_BOOKS,
                               DBQUERY_INDEX_BOOKS,
                               DBQUERY_CREATE_BOOKUSER,
                               DBQUERY_CREATE_PAGES,
                               DBQUERY_CREATE_PAGEUSER,
                               DBQUERY_CREATE_TAGS,
                               DBQUERY_CREATE_TAGBOOK,
                               DBQUERY_CREATE_CATEGORIES,
                               DBQUERY_CREATE_CATBOOK,
                               nil];
    }
    return self;
}
@interface DBManager : NSObject <CommsManagerDelegate> {
    __weak id <DBMDelegate>  delegate;
    DB *database;
    NSString *dbFullPath;
}


@property (nonatomic, weak) id <DBMDelegate> delegate;
@property (nonatomic, strong) DB *database;
@property (nonatomic, strong) NSString *dbFullPath;
-(BOOL) parseMetaDataDict: (NSDictionary*) serverDict {

    /// Getting the lists of books from the Server's JSON dictionary
    NSDictionary *dictAllBooks = [serverDict objectForKey:@"Books"];

    int bookNum=0;
    int totalBooks = [[dictAllBooks valueForKey:@"Book"] count];

    // Updates the UI
    [delegate dbmNumberOfBooksProcessedByDB:totalBooks];

    /// Browsing it book by book
    for (id serverDictBook in [dictAllBooks valueForKey:@"Book"]){
        bookNum++;

        /// Trimming book from the server and placing it into the local book dictionary
        BookDict *bookDict = [[BookDict alloc]initWithServerDict:serverDictBook];

        __block BOOL isError = NO;

        /// Sending the queries into the serial queue
        [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
            /// Inserting book into the BOOKS table
            if(![db executeUpdate:DBUPDATE_INSERT_BOOK withParameterDictionary:bookDict.dictionary])
            {
                isError = YES;
                DDLogWarn(@"%@", [db lastErrorMessage]);
                *rollback = YES;
                return;      // Carefull - It returns from the transaction, not the function
            }
        }];

        if (isError){
            return NO;
        }

        __block NSString *bookID;

        /// Getting the bookID automatically generated by the DB
        NSString *query = [NSString stringWithFormat:@"SELECT bookID FROM BOOKS where isbn = '%@'", [bookDict.dictionary valueForKey:@"isbn"]];
        [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
            FMResultSet *result = [db executeQuery:query];
            if([result next])
            {
                int num = [result intForColumnIndex:0];
                bookID = [NSString stringWithFormat:@"%d", num];
            }
            else{
                isError = YES;
                DDLogWarn(@"%@", [db lastErrorMessage]);
                *rollback = YES;
                return;      // Carefull - It returns from the transaction, not the function
            }
        }];

        if (isError){
            return NO;
        }


        int numPages = [[serverDictBook objectForKey:@"numberOfPages"] intValue];

        /// Browsing the book page by page
        ///VCC Today probably replace by 0
        for (int i=1; i<=numPages; i++)
        {
            PageDict *pageDict = [[PageDict alloc]initWithPage:i andBookID:bookID ofServerDict:serverDictBook];

            __block BOOL isError = NO;

            /// Sending the queries into the serial queue
            [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
                /// Inserting page into the PAGES table
                if(![db executeUpdate:DBUPDATE_INSERT_PAGE withParameterDictionary:pageDict.dictionary])
                {
                    isError = YES;
                    DDLogWarn(@"%@", [db lastErrorMessage]);
                    *rollback = YES;
                    return;      // Carefull - It returns from the transaction, not the function
                }
            }];

            if (isError)
            return NO;
        }


        __block NSString *catID;

        /// Browsing the book categories one by one
        for (id serverCatDict in [serverDictBook valueForKey:@"categories"]){

            __block BOOL isError = NO;

            /// Sending the queries into the serial queue
            [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
                /// Inserting row into the CATEGORY table
                if(![db executeUpdate:DBUPDATE_INSERT_CATEGORY withParameterDictionary:serverCatDict])
                {
                    isError = YES;
                    DDLogWarn(@"%@", [db lastErrorMessage]);
                    *rollback = YES;
                    return;      // Carefull - It returns from the transaction, not the function
                }

                /// Getting the catID automatically generated by the DB
                NSString *query = [NSString stringWithFormat:@"SELECT catID FROM CATEGORIES where name = '%@'", [serverCatDict valueForKey:@"name"]];

                FMResultSet *result = [db executeQuery:query];
                if([result next])
                {
                  catID = [result stringForColumnIndex:0];
                }
                else{
                  isError = YES;
                  DDLogError(@"%@", [db lastErrorMessage]);
                  *rollback = YES;
                  return;      // Carefull - It returns from the transaction, not the function
                }

              CatBookDict *catBookDict = [[CatBookDict alloc] initWithCatID:catID andBookID:bookID];

              /// Inserting row into the CATBOOK table
              if(![db executeUpdate:DBUPDATE_INSERT_CATBOOK withParameterDictionary:catBookDict.dictionary])
              {
                isError = YES;
                DDLogError(@"%@", [db lastErrorMessage]);
                *rollback = YES;
                return;      // Carefull - It returns from the transaction, not the function
              }

          }];

          if (isError)
              return NO;

        }


//      /// Browsing the book categories one by one
//      for (id serverCatDict in [serverDictBook valueForKey:@"name"]){
//        
//          __block BOOL isError = NO;
//
//        CatBookDict *catBookDict = [[CatBookDict alloc] initWithCatID:[serverCatDict valueForKey:@"catID"]];
//
//          /// Sending the queries into the serial queue
//          [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
//                                  andBookID:bookID];
//              /// Inserting row into the CATBOOK table
//              if(![db executeUpdate:DBUPDATE_INSERT_CATBOOK withParameterDictionary:catBookDict.dictionary])
//              {
//                isError = YES;
//                DDLogVerbose(@"%@", [db lastErrorMessage]);
//                *rollback = YES;
//                return;      // Carefull - It returns from the transaction, not the function
//              }
//          }];
//                                      
//          if (isError)
//          return NO;
//
//      }
      [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
        FMResultSet *result = [db executeQuery:query];
        if([result next])
        {
          int num = [result intForColumnIndex:0];
          bookID = [NSString stringWithFormat:@"%d", num];
        }
        else{
          isError = YES;
          DDLogError(@"%@", [db lastErrorMessage]);
          *rollback = YES;
          return;      // Carefull - It returns from the transaction, not the function
        }
      }];

      if (isError){
        return NO;
      }



        /// Browsing the book tags one by one
        for (id serverTagDict in [serverDictBook valueForKey:@"tags"]){
//            TagDict *tagDict = [[TagDict alloc] initWithServerDict:serverTagDict[0]];
//            TagBookDict *tagBookDict = [[TagBookDict alloc] initWithTagID:[serverTagDict valueForKey:@"tagID"]
//                                                                andBookID:bookID];
            __block BOOL isError = NO;

            /// Sending the queries into the serial queue
            [database.dbqueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
                /// Inserting tag into the TAGS table
                if(![db executeUpdate:DBUPDATE_INSERT_TAG withParameterDictionary:serverTagDict])
                {
                    isError = YES;
                    DDLogError(@"%@", [db lastErrorMessage]);
                    *rollback = YES;
                    return;      // Carefull - It returns from the transaction, not the function
                }

//                /// Inserting the row into the TAGBOOK table
//                if(![db executeUpdate:DBUPDATE_INSERT_TAGBOOK withParameterDictionary:tagBookDict.dictionary])
//                {
//                    isError = YES;
//                    DDLogVerbose(@"%@", [db lastErrorMessage]);
//                    *rollback = YES;
//                    return;      // Carefull - It returns from the transaction, not the function
//                }

            }];

            if (isError)
                return NO;
        }

        // Updates the UI
        [delegate dbmBookProcessedByDB:bookNum];

    }

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    if (![defaults objectForKey:@"firstSynced"]){
        [defaults setObject:[NSDate date] forKey:@"firstSynced"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }

    return TRUE;
未对进度条进行更新。我认为调度异步是不必要的。调试表明,它通过了dispatch_async,从未进入内部


是FMDB队列阻塞了整个主线程。如何在每次处理书籍时对标签进行定期更新

在FMDB中,
dispatch\u sync
功能用于将事务块放入串行队列。 对于
dispatch\u sync
来说:

作为一种优化,此函数调用当前 尽可能地穿线

我认为这就是调用
-inTransaction:
可能会阻塞主线程的原因

尝试从后台线程调用
-inTransaction:
。为此,您可以将
for
循环的主体放入via CGD,如下所示:

-(BOOL) parseMetaDataDict: (NSDictionary*) serverDict {
    ...

    /// Browsing it book by book
    for (id serverDictBook in [dictAllBooks valueForKey:@"Book"]){
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void){

            ... all -inTransaction: calls are here

            dispatch_async(dispatch_get_main_queue(), ^(void){
                // Updates the UI
                [delegate dbmBookProcessedByDB:bookNum];
            });

        });
    }
注意:为了使代码看起来清晰,最好在一个范围内的线程之间跳转,因此您还可以将
调度异步(dispatch\u get\u main\u queue(),…)
-dbmBookProcessedByDB
移动到
主体内,如上面的代码所示