NSOperationQueue и UITableView - PullRequest
       7

NSOperationQueue и UITableView

2 голосов
/ 17 марта 2011

Я загружаю некоторые данные из базы данных SQLite для отображения в UITableView.Чтобы убедиться, что пользователь не заблокирован и таблица отображается быстро, я создаю очередь и добавляю операцию с базой данных для выполнения в фоновом режиме.

Добавление хорошее и работает нормально, но по какой-то причине случайнонекоторые строки не обновляются с данными!

Я знаю, что данные установлены правильно, так как когда я нажимаю на строку, строка обновляется с моими данными, но я не могу найти способ обновитьпользовательский интерфейс!Я пробовал все, включая setNeedDisplay и т. Д., Но ничего не работает!

Вот мой код:

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

Ответы [ 2 ]

4 голосов
/ 17 марта 2011

Ваша логика несовершенна, и я думаю, что вы будете испытывать ужасную производительность, а также проблемы, которые вы уже испытываете.Было бы лучше запустить полную Операцию, чтобы загрузить все ваши данные или хотя бы часть ваших данных, а затем попросить таблицу перезагрузить после ее завершения.

То, как вы делаете это сейчас, состоит в том, что каждая ячейкапопадает в базу данных и выбирает одну строку и нигде не кэширует эти данные (то есть, если они прокручиваются вне поля зрения и затем снова включаются, им придется снова обращаться к базе данных).Кроме того, нет кода рисования, вызываемого в этой ячейке, когда операция завершается (поэтому она не отображается, пока вы не щелкнете по ней, вызывая вызов рисования).

Вы должны загрузить все эти данные вмассив пользовательских объектов.После загрузки вы должны перезагрузить таблицу и использовать вновь заполненный массив, чтобы установить свои свойства в ячейке.

1 голос
/ 17 марта 2011

Вы обновляете свой пользовательский интерфейс из фоновой ветки, что неправильно.Вся работа с пользовательским интерфейсом должна выполняться в главном потоке.Попробуйте переместить все взаимодействия с cell в основной поток, передав данные из фонового потока в NSDictionary.

См. executeSelectorOnMainThread: withObject: waitUntilDone: .Также прочитайте Потоки и ваш пользовательский интерфейс в Руководстве по программированию потоков Apple.

@ theChrisKent высказал хорошие замечания по поводу производительности, хотя эта проблема с потоками, скорее всего, является причиной вашего неустойчивого поведения.

...