2015-07-16 12 views
12

Ho scritto una query che si attiva su viewWillAppear. Tornando a quello schermo con una navigazione veloce si verifica un arresto anomalo a sqlite3_prepare_v2.
Quello che sto assumendo è che l'arresto anomalo è dovuto alla query precedente non finalizzata.
Sto chiamando l'operazione del database utilizzando dispatch_async mentre sto aggiornando per la prima volta i dati remoti e quindi salvandoli nel database.
Il codice simile a questo:sqlite3_prepare_v2 arresto anomalo - Già in esecuzione la query precedente

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]; 

        }); 
       }); 

La query è la seguente:

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

sto chiamando GetAllActivities da viewWillAppear:

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

I vostri pensieri e soluzione?

+1

Quindi, quando l'app si arresta in modo anomalo (o si blocca), si hanno chiamate sqlite3 sulla stessa connessione al database da più thread? Se questo è il caso, forse c'è una soluzione piuttosto semplice. Inoltre, hai qualche informazione sull'arresto dalla console di debug? – Artal

+1

@Artal: le chiamate di database sono in una classe singleton, penso che condividano la stessa connessione al database. Nulla appare sulla console. – Nitish

+1

e le chiamate vengono effettuate da thread diversi allo stesso tempo? – Artal

risposta

6

Creare una coda di serie con:

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

e che dovrebbe gestire l'accesso sequenziale al database.

+1

Questo ha ritardato l'arresto di alcune altre navigazioni, ma poi ho nuovamente ricevuto l'arresto. – Nitish

+0

@Nitish Hmmm OK. Non hai segnalato errori nel tuo codice sqlite3. Si prega di aggiornarlo e vedere se ti dà qualche indizio. In caso contrario, mi piacerebbe vedere lo stacktrace. – trojanfoe

+0

Fatto così ma l'errore non è ottenibile. È bloccato a sqlite3_prepare_v2. Ho aggiornato il mio codice nella domanda. – Nitish

4

Una cosa che noto è in viewWillAppear si chiama il metodo getActivities ma si incolla un corpo di GetAllActivities. È un po 'lungo, ma sei sicuro di chiamare correttamente il tuo metodo GetAllActivities? E da dove viene chiamato il metodo GetAllInvitations?

Problemi correlati