2015-07-16 5 views
12

Ich habe eine Abfrage geschrieben, die auf viewWillAppear ausgelöst wird. Wenn Sie mit einer schnellen Navigation zu diesem Bildschirm zurückkehren, führt dies zu einem Absturz bei sqlite3_prepare_v2.
Ich nehme an, dass der Absturz aufgrund der vorherigen Abfrage nicht abgeschlossen ist.
Ich rufe die Datenbankoperation mit dispatch_async auf, während ich zuerst entfernte Daten aktualisiere und sie dann in der Datenbank speichere.
Der Code sieht wie folgt aus:sqlite3_prepare_v2 Absturz - Bereits vorhergehende Abfrage ausgeführt

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

        }); 
       }); 

Die Abfrage lautet wie folgt:

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

Ihre Gedanken und Lösung:

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

I GetAllActivities von viewWillAppear nenne?

+1

Also, wenn die App abstürzt (oder stecken bleibt), haben Sie sqlite3 Aufrufe auf der gleichen Datenbankverbindung von mehreren Threads? Wenn das der Fall ist, gibt es möglicherweise eine ziemlich einfache Lösung. Außerdem - haben Sie irgendwelche Informationen über den Absturz von der Debug-Konsole? – Artal

+1

@Artal: Datenbankaufrufe in einer Singleton-Klasse, ich denke ja, sie teilen sich die gleiche Datenbankverbindung. Nichts erscheint auf der Konsole. – Nitish

+1

und werden die Anrufe von verschiedenen Threads gleichzeitig ausgeführt? – Artal

Antwort

6

Erstellen Sie eine serielle Warteschlange mit:

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

und das sollte sequenziellen Zugriff auf die Datenbank verwalten.

+1

Dies verzögerte den Absturz auf ein paar mehr Navigation, aber dann erhielt ich erneut den Absturz. – Nitish

+0

@Nitish Hmmm OK. Sie haben keine Fehlermeldung in Ihrem SQLite3-Code. Bitte aktualisieren Sie es und sehen Sie, ob es Ihnen Hinweise gibt. Wenn nicht, würde ich gerne den StackTrace sehen. – trojanfoe

+0

Fertig, aber der Fehler ist nicht getable. Es ist bei sqlite3_prepare_v2 fest. Ich habe meinen Code in der Frage aktualisiert. – Nitish

4

Eine Sache, die ich bemerke, ist in viewWillAppear Sie rufen Methode getActivities, aber Sie fügen einen Körper von GetAllActivities. Es ist eine Art lange, aber Sie sicher, dass Sie Ihre GetAllActivities Methode richtig aufrufen? Und woher GetAllInvitations Methode aufgerufen werden?

Verwandte Themen