views:

378

answers:

1

I have a view with a UILabel and a UITableView. I'm using this code to get a string from a database:

-(void)getOneQuestion:(int)flashcardId categoryID:(int)categoryId {
    flashCardText=[[NSString alloc] init];
    flashCardAnswer=[[NSString alloc] init];

    NSString *martialStr=[NSString stringWithFormat:@"%d", flashcardId];    
    NSString *queryStr=[[NSString alloc] initWithString:@"select flashCardText,flashCardAnswer,flashCardTotalOption from flashcardquestionInfo where flashCardId="];
    queryStr=[queryStr stringByAppendingString:martialStr]; 

    NSString *martialStr1=[NSString stringWithFormat:@"%d", categoryId];    
    NSString *queryStr2=[[NSString alloc] initWithString:@" and categoryId="];
    queryStr2=[queryStr2 stringByAppendingString:martialStr1];  
    queryStr=[queryStr stringByAppendingString:queryStr2];  

    unsigned int lengthOfString=[queryStr length];
    char temp2[lengthOfString +1];
    strcpy(temp2, [queryStr cStringUsingEncoding:NSUTF8StringEncoding]);    
    clsDatabase *clsDatabaseObject = [[clsDatabase alloc] init];    
    sqlite3_stmt *dataRows = [clsDatabaseObject getDataset:temp2];
    while(sqlite3_step(dataRows) == SQLITE_ROW) {    
        flashCardText =[NSString stringWithUTF8String:(char *)sqlite3_column_text(dataRows,0)];
        flashCardAnswer=[NSString stringWithUTF8String:(char *)sqlite3_column_text(dataRows,1)];
        flashCardTotalOption=sqlite3_column_int(dataRows,2);
    }
    sqlite3_reset(dataRows);
    sqlite3_finalize(dataRows);
    [clsDatabaseObject release];    
}

When I click on the table cell, the string value (flashCardAnswer) shows invalid.

+2  A: 

Although this code snippet doesn't seem to show where the string value is assigned to the UI element, it would seem that the problem could stem from your use of +[NSString stringWithUTF8String:] inside the while loop. This returns an autoreleased string which you much retain if you want to use it outside the scope of the method. Since those appear to be instance variables that you use in another part of the code to change the UI, you have a few options:

  1. Send a -retain to each of them before exiting the method.
  2. Use +alloc and -initWithUTF8String:.
  3. Use a setter method or property that takes care of the details for you. (Thanks, Chuck!)

As a bonus, I have a few other related suggestions.

  • You're leaking memory by allocating strings for flashCardText and flashCardAnswer at the start of the method, since you overwrite them in the while loop.
  • Use -[NSString getCString:maxLength:encoding:] to write the query string into a char* buffer without the strcpy() call, or just use the char* from -cStringUsingEncoding: directly.
  • There is a lot of potential for simplifying the construction of your query string — definitely investigate NSMutableString. For example...
    NSMutableString* query = [[NSMutableString alloc] initWithString:@"select flashCardText,flashCardAnswer,flashCardTotalOption from flashcardquestionInfo"];
    [query appendFormat:@" where flashCardId=%d", flashcardId];
    [query appendFormat:@" and categoryId=%d", categoryId];
    clsDatabase *clsDatabaseObject = [[clsDatabase alloc] init];
    sqlite3_stmt *dataRows = [clsDatabaseObject getDataset:[query cStringUsingEncoding:NSUTF8StringEncoding]];
Quinn Taylor
IMO, the more obvious answer than either retaining explicitly or using alloc explicitly is to keep the string creation code but use a setter to set the instance variables.
Chuck
Agreed, can't believe that obvious approach escaped me. :-)
Quinn Taylor
it shows syntax error before 'cStringUsingEncoding' amd i have already used a setter to set instance variables
Rahul Vyas
and i am passing flashcardanswer to another string on cell's click then doing furthur calculation based on that string.i am adding that code to my question for more detail about the question
Rahul Vyas
Sorry, I had missed the method name to clsDatabaseObject. Fixed now.
Quinn Taylor