2012-05-15 47 views
6

Tôi có UITableView. theo phương pháp tableView:cellForRow:atIndexPath: (khi dữ liệu được điền vào ô) Tôi đã triển khai một số loại tải chậm. Nếu không có đối tượng cho khóa (key == số hàng) trong rowDataNSDictionary, chương trình sẽ khởi chạy phương thức requestDataForRow: ở chế độ nền. do đó, dữ liệu trong các ô được điền một chút sau khi ô hiển thị. Dưới đây là các mã:Tối ưu hóa tải tối ưu UITableView

static int requestCounter=0; 

-(void)requestDataForRow:(NSNumber *)rowIndex 
{ 
    requestCounter++; 
    //NSLog(@"requestDataForRow: %i", [rowIndex intValue]); 
    PipeListHeavyCellData *cellData=[Database pipeListHeavyCellDataWithJobID:self.jobID andDatabaseIndex:rowIndex]; 
    [rowData setObject:cellData forKey:[NSString stringWithFormat:@"%i", [rowIndex intValue]]]; 
    requestCounter--; 

    NSLog(@"cellData.number: %@", cellData.number); 

    if (requestCounter==0) 
    { 
     //NSLog(@"reloading pipe table view..."); 
     [self.pipeTableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO]; 
    }; 
} 

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

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; 
    [[NSBundle mainBundle] loadNibNamed:@"PipesForJobCell" owner:self options:nil]; 
    cell = pipeCell; 
    self.pipeCell = nil; 


    PipeListHeavyCellData *cellData=[[PipeListHeavyCellData alloc] init]; 

    if ([rowData objectForKey:[NSString stringWithFormat:@"%i", indexPath.row]]==nil) 
    { 
     //NSLog(@"  nil data for row: %i", indexPath.row); 
     [self performSelectorInBackground:@selector(requestDataForRow:) withObject:[NSNumber numberWithInt:indexPath.row]]; 
    } 
    else 
    { 
     //NSLog(@"  has data for row: %i", indexPath.row); 
     PipeListHeavyCellData *heavyData=[[PipeListHeavyCellData alloc] init]; 
     heavyData=(PipeListHeavyCellData *)[rowData objectForKey:[NSString stringWithFormat:@"%i", indexPath.row]]; 
     cellData._id=[heavyData._id copy]; 
     cellData.number=[heavyData.number copy]; 
     cellData.status=[heavyData.status copy]; 
}; 

Mã này hoạt động, mọi thứ đều OK, NHƯNG bàn của tôi có 2000 hàng và Nếu người dùng cuộn từ tế bào với chỉ số 10 đến ô với chỉ số 2000 rất nhanh chóng. Ông phải chờ một thời gian dài cho đến khi tất cả các yêu cầu dữ liệu kéo sẽ hoàn thành (đối với các hàng 11, 12, 13, ..., 2000) khiến các hàng đó trở nên hiển thị trong khi người dùng đang cuộn chế độ xem bảng để phương pháp requestDataForRow được gọi cho họ.

Làm cách nào để tối ưu hóa những thứ đó?

+1

Đây là một câu hỏi tuyệt vời với cùng một vấn đề với một số giải pháp rất tốt (với mã): http://stackoverflow.com/q/7567827/937822 – lnafziger

Trả lời

4

Tôi phải làm điều tương tự. Bạn sẽ cần tạo một hàng đợi xử lý các mục được thêm gần đây nhất trước tiên.

Ví dụ: người dùng mở bảng và 10 yêu cầu được xếp hàng đợi. Bạn dequeue đối tượng đầu tiên và bắt đầu lấy dữ liệu cho hàng đầu tiên. Tuy nhiên, người dùng sau đó cuộn xuống hàng 31-40. Sau đó, bạn sẽ phải chèn các hàng đó trước 10 hàng đầu tiên trong hàng đợi của bạn bởi vì chúng hiện được ưu tiên cao hơn. Điều quan trọng là bạn không ngay lập tức bắt đầu 10 yêu cầu cùng một lúc, nhưng xử lý chúng theo thứ tự. Bằng cách đó, khi người dùng cuộn, bạn chỉ "lãng phí" một yêu cầu - yêu cầu cuối cùng được thực hiện.

Cách dễ dàng để thực hiện điều này là sử dụng [tableView indexPathsForVisibleRows].

+0

Cảm ơn, suy nghĩ của tôi là tương tự. – user1385666