2010-01-10 44 views
3

我在我的iPhone項目中有以下功能,它工作得很好......除非查詢沒有返回任何內容,然後應用程序崩潰。根本沒有任何斷點被激活,調試是一種痛苦!如果沒有行返回iphone的sqlite查詢崩潰

我知道這個工作,因爲我通過在數據庫中的靜態東西,它會返回一個值。

-(NSString *)getSomeText:(NSString *)toPass { 
    sqlite3 *database; 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *databasePath = [documentsDirectory stringByAppendingPathComponent:@"sf.sqlite"]; 

    int strLength = 0; 
    strLength = [toPass length]; 

    if (strLength <3) 
     return @"Unknown"; 


    NSString *MIDstr; 
    NSMutableString * toPass Copy = [NSMutableString stringWithString:toPass]; 
    MIDstr = [toPassCopy substringWithRange:NSMakeRange(0, 3)]; 


    // Open the database from the users filessytem 
    if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) { 
     // Setup the SQL Statement and compile it for faster access 
     NSString *BaseSQL = [NSString stringWithFormat:@"select * from MIDS where MID = '%@'",MIDstr]; 
     NSLog(BaseSQL); 

     const char *sqlStatement = [BaseSQL UTF8String]; 
     //NSLog(BaseSQL); 
     sqlite3_stmt *compiledStatement; 
     if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) { 
      // Loop through the results and add them to the feeds array 

      while(sqlite3_step(compiledStatement) == SQLITE_ROW) { 


        NSString *aName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)]; 
        NSString *returnString = [NSString stringWithFormat:@"%@",aName]; 
        return returnString;     

      } 
     } 
     // Release the compiled statement from memory 
     sqlite3_finalize(compiledStatement); 

    } 
    sqlite3_close(database); 

} 

回答

4

A.如果sqlite3_step不返回任何行,你崩潰,因爲你已經宣佈你正在返回的NSString,但如果沒有行,你什麼都不返回。 調用者將嘗試從堆棧中讀取NSString,因此最終導致垃圾回收。

要快速解決問題,寫:

sqlite3_close(database); 
    return nil; 
} 

,並確保來電處理結果。

B /如果你有數據,你的代碼永遠不會調用sqlite3_finalizesqlite3_close因爲您返回早期:

while(sqlite3_step(compiledStatement) == SQLITE_ROW) { 
    [..] 
    return returnString; 
+0

現貨謝謝! 您是否在執行return returnString之前說完並關閉? – 2010-01-10 10:08:13

+0

這通常是通過聲明一個本地NSString來設置的,在進行任何清理之後,計算它並在方法的最後返回。 順便說一句,不從非void方法返回值是一個編譯器警告 - 您可能想要更仔細地閱讀XCode的輸出或打開「將警告視爲錯誤」 – diciu 2010-01-10 10:14:43

0
while (sqlite3_step(sqlstatement) == SQLITE_ROW) 
      { 
       //Your code goes here 

      } 

      sqlite3_finalize(sqlstatement); 
      sqlite3_close(databaseRefObj); 

關閉數據庫後完成您的發言while循環這幫了我,