Search code examples
objective-cmacostableviewnstableviewosx-snow-leopard

objective c - NSTableView Reload Data


I'm developing an application, which works with tableview. I need to load VERY HUGE amount of data into my table view (up to 500k elements). When i load data, i show animation on another view. Animation runs in main thread. Loading data is on background thread. And i perform reload data in table view on background thread too. But i want to make it possible to cancel this operation.

And what i noticed is that fetching up my data lasts for several seconds while loading this data into table view can take up to minute. So, my question is: is there any way to interrupt loading data into table view? I've read tableview programming guide in documentation, but didn't found anything about such things there.

My target SDK is 10.6. I use cell-based tableview


Solution

  • I've got a solution, that suits me. So, what i did was adding a category to NSTableView with one property: lastRowVisible. I've overrode it's getter in such a way:

    - (BOOL)isLastRowVisible
    {
        NSRect bounds = self.superview.bounds;
        bounds.origin.y += bounds.size.height - 1;
        NSInteger index = [self rowAtPoint:bounds.origin];
        return index == ([self.dataSource numberOfRowsInTableView:self] - 1);
    }
    

    In my viewController i've added some properties:

    @property (nonatomic, assign, readwrite) NSInteger pageNumber;
    @property (nonatomic, assign, readwrite) NSInteger pageLimit;
    @property (nonatomic, assign, readwrite) BOOL canLoadMoreData;
    

    When I need loading data into tableView i do such a manipulation:

    self.pageLimit = kDefaultPageLimit;
    self.pageNumber = kDefaultPageNumber;
    
    NSInteger visibleNumberOfRows = (self.pageNumber + 1) * self.pageLimit;
    self.myDataArray = DataArray;
    self.canLoadMoreData = (self.myDataArray.count < visibleNumberOfRows);
    
    [self.myTableView reloadData];
    [self.myTableView scrollRowToVisible:0];
    

    And in my delegate methods i just check whether i need to load more data or not:

    - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
    {
        return self.myData.count < self.visibleNumberOfRows ? self.myData.count : self.visibleNumberOfRows;
    }
    
    - (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
    {   
        if (tableView.lastRowVisible && self.canLoadMoreData)
        {
            self.pageNumber ++;
            if (self.myData.count < self.visibleNumberOfRows)
            {
                self.canLoadMoreData = NO;
            }
            [tableView reloadData];
        }
        // configure and return cell
    }
    

    Such a solution works fine for me and suits all my needs.