2010-01-10 43 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循环这帮了我,