繁体   English   中英

NSOperationQueue和UITableView

[英]NSOperationQueue and UITableView

我正在从SQLite数据库加载一些数据,以显示在UITableView 为了确保用户没有被阻塞并且表可以快速显示,我创建了一个队列并添加了要在后台执行的数据库操作。

添加是好的并且可以正常工作,但是由于某些原因,某些行不会随数据一起更新!

我知道数据设置正确,因为当我单击该行时,该行将用我的数据进行更新,但是我似乎找不到更新UI的方法! 我已经尝试了一切,包括使用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];
}

您的逻辑有缺陷,我认为您将体验到糟糕的性能以及已经遇到的问题。 最好启动整体操作以加载所有数据或至少部分数据,然后要求表完成时重新加载。

现在,您的操作方式是每个单元都在访问数据库并选择一行,而不在任何地方缓存该数据(这意味着如果它滚动到视图外然后再次返回,则必须再次访问数据库)。 另外,操作完成时,此单元格上没有调用绘制代码(这就是为什么直到单击它会引起绘制调用后它才会显示的原因)。

您应该将所有这些数据加载到自定义对象的数组中。 加载后,您应该重新加载表并使用新填充的数组在单元格中设置属性。

您正在从后台线程更新用户界面,这是错误的。 所有用户界面工作必须在主线程上完成。 尝试将与cell所有交互都移到主线程,将数据从后台线程传递到NSDictionary

请参见performSelectorOnMainThread:withObject:waitUntilDone:。 另请参阅《 Apple线程编程指南》中的“ 线程和用户界面 ”。

@theChrisKent很好地说明了性能,尽管此线程问题很可能是您行为失常的原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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