2010-01-19 80 views
2

我已經閱讀了許多有關UITableViews不在iPhone上刷新的主題,但找不到與我的情況相匹配的任何內容,所以我正在尋求幫助。在我的類中,它擴展了UIViewController,我有一個TableView和一個'ElementList'(它是NSMutableArray的包裝)用作數據源。iPhone:UITableView不刷新

單獨的線程通過'updateList:'方法向數組添加一個新的元素。 發生這種情況時,我希望tableView自動刷新,但這不會發生。

通過調試我的應用程序,我可以看到'cellForRowAtIndexPath'永遠不會被調用,我不知道爲什麼。

我試着添加一個Observer,它調用'reloadTableView'方法(實際上調用它),但tableView沒有更新。

這是我的代碼:

#import <UIKit/UIKit.h> 

@interface ListViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> 
{ 
    UITableView *tableView; 
    ElementList *elementList; // Wrapper for NSMutableArray 
} 

// Called by someone else, triggers the whole thing 
-(void)updateList:(Element *)element; 

// Added out of desperation 
-(void)reloadTableView; 

@end 


@implementation ListViewController 

-(void)loadView 
{ 
    // Create the TableView 
    tableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStylePlain]; 
    assert(tableView != nil); 
    tableView.delegate = self; 
    tableView.dataSource = self; 
    [tableView reloadData]; 

    self.view = tableView; 

    // Added out of desperation 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadTableView) name:@"UpdatedListNotification" object:nil]; 
} 

-(void)reloadTableView 
{ 
    // Try anything 
    [tableView reloadData]; 
    [tableView setNeedsLayout]; 
    [tableView setNeedsDisplay]; 
    [tableView reloadData]; 
    [self.view setNeedsLayout]; 
    [self.view setNeedsDisplay]; 
} 

// Called by someone else, triggers the whole thing 
-(void)updateList:(Element *)element 
{ 
    assert(element != nil); 
    [elementList addElement:element]; 
    [element release]; 

    // Notify the observer, which should update its table view 
    [[NSNotificationCenter defaultCenter] postNotificationName:@"UpdatedListNotification" object:self]; 
} 

// TableView Delegate protocol 
- (void)tableView:(UITableView *)table didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    Element *selected_element = [elementList getElementAtIndex:indexPath.row]; 
    if (selected_element == nil) 
    { 
     NSLog(@"ERROR: Selected an invalid element"); 
     return; 
    } 
    [table deselectRowAtIndexPath:indexPath animated:YES]; 

    NSLog(@"Selected %@", selected_element.name); 
} 

// TableView Data Source protocol 
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 
    return 1; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    return [elementList count]; 
} 

- (UITableViewCell *)tableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{  
    static NSString *CellIdentifier = @"Cell"; 
    UITableViewCell *cell = [table dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) 
    { 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 
    } 

    // Set the cell label 
    cell.textLabel.text = [[elementList getElementAtIndex:indexPath.row] name]; 
    cell.textLabel.frame = cell.bounds; 
    cell.textLabel.textAlignment = UITextAlignmentLeft; 
    return cell; 
} 

@end 

任何幫助是極大的讚賞,謝謝。

回答

13

通知在與調用方相同的線程中執行。更新UI確實應該在主線程中完成,所以你應該在主線程中調用-reloadData

-(void)updateList:(Element *)element 
{ 
    assert(element != nil); 
    [elementList addElement:element]; 

    [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil]; 
} 

還要注意的是,你不應該釋放一個對象,你沒有自己。所以不要在你的-updateList方法中調用[元素釋放]。該版本應該由函數的調用者調用。

+0

你搖滾!!!謝謝:) – rippeltippel 2010-01-19 13:30:41

+1

我很高興能有所幫助。當你在這裏時,考慮通過點擊左邊的大'V'來接受答案:-) – 2010-01-19 14:01:17

+0

這使我瘋狂 - 謝謝指出! – theTRON 2012-05-21 03:51:48

2

這並不適合我 - 但非常接近。我採用的方法是 -

[self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES]; 
0

你也可以做

[self performSelectorOnMainThread:@selector(reloadTable) withObject:nil waitUntilDone:YES]; 

,這樣就可以實現對一個的ViewController方法要做到這一點,你需要的所有UI的東西。

-(void)reloadTable 
{ 
    [self.tableView reloadData]; 
}