簡體   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