2010-01-19 58 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]; 
}