简体   繁体   中英

NSOperationQueue and UITableView

I'm loading some data from a SQLite database to be displayed in a UITableView . To make sure the user is not blocked and the table is displayed quickly I'm creating a queue and adding the database operation to be executed in the background.

The add is good and works fine but for some reason randomly some of the rows are not updated with the data!

I know the data is set correctly as when I click on the row the row is updated with my data but I can't seem to find a way to update the UI! I've tried everything including using setNeedDisplay and so on but nothing works!

Here is my code:

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell* cell = (UITableViewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
        cell.textLabel.textAlignment = UITextAlignmentRight;
        cell.textLabel.numberOfLines = 0;
        cell.textLabel.font = [UIFont systemFontOfSize:14];
    }

    cell.accessoryType = UITableViewCellAccessoryNone;
    cell.textLabel.text = @"Loading ...";
    cell.tag = indexPath.row;

    NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self 
                                                                     selector:@selector(setCellData:) 
                                                                       object:cell];

    [queue addOperation:op];
    [op release];

    return cell;
}


- (void) setCellData:(UITableViewCell *)cell{

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    sqlite3_stmt            *statement2;

    NSString *sqlStr = [NSString stringWithFormat:@"SELECT * FROM poemdata WHERE catid='%d' GROUP BY poemid LIMIT 1 OFFSET %d",catId,cell.tag];
//  NSLog(@"%@",sqlStr);
    sqlite3_prepare_v2(database, [sqlStr cStringUsingEncoding:NSASCIIStringEncoding], -1, &statement2, nil);

    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    if(sqlite3_step(statement2) == SQLITE_ROW){
        cell.textLabel.text = [[NSString alloc] initWithUTF8String: (char *)sqlite3_column_text(statement2, 3)];
        cell.tag = sqlite3_column_int(statement2, 6);
    }else{
        cell.textLabel.text = @"Error";
    }
    sqlite3_finalize(statement2);

    [pool release];
}

Your logic is flawed and I think you will experience terrible performance as well as the problems you are already experiencing. It would be better to launch an overall Operation to load all your data or at least a portion of your data and then asking the table to reload when it finishes.

The way you are doing it now is that every cell is hitting the database and selecting one row and not caching this data anywhere (meaning if it scrolls out of view and then back in again it will have to hit the database again). In addition there is no drawing code called on this cell when the operation finishes (which is why it doesn't show up until you click it causing a draw call).

You should load all of this data into an array of custom objects. Once loaded you should reload the table and use the newly filled array to set your properties in the cell.

You're updating your user interface from your background thread, which is wrong. All user interface work must be done on the main thread. Try moving all interaction with cell to the main thread, passing the data from the background thread in an NSDictionary .

See performSelectorOnMainThread:withObject:waitUntilDone: . Also read Threads and Your User Interface in Apple's Threading Programming Guide.

@theChrisKent made good points about performance, though this threading issue is more likely the cause of your erratic behavior.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM