UIView和UITableView,reloadData奇怪的延迟

时间:2010-09-01 05:46:03

标签: iphone uitableview uiviewcontroller

我对视图控制器的重绘有些奇怪。视图控制器包含一个UITableView和一个微调器。

我有一个 updateFeed 函数(由IBOutlet触发),它将微调器放在我的视图控制器前面,并放置一个 doUpdate 函数进入NSOperationQueue。

- (void)updateFeed {
    [self showMuar];
    ResourceLoader *loader = [ResourceLoader sharedResourceLoader];
    [loader updateFeed:[self feed] forDelegate:self];
    isReloading = YES;
}
- (id<ResourceToken>)updateFeed:(Feed *)feed forDelegate:(id)delegate {
     return [self queueOperation:[[Operation alloc] initWithObject:feed withSelector:@selector(doUpdate) delegate:delegate]];
}

doUpdate 函数调用解析器(startParserWithAdd :)函数,该函数从Internet检索内容并为UITableView格式化此内容,然后执行 [tableView reloadData ]

- (NSError *)doUpdate {
    [self startParserWithAddThreaded:NO];
    return nil;
}
- (void)startParserWithAddThreaded:(BOOL)add {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    [self startParserWithAdd:add];
    [pool release];
}

...解析器函数中的某个地方(startParserWithAdd :)

[tableView setDataSource:self];
[tableView reloadData];

完成 doUpdate 后没有错误,感谢我的操作类,我的视图控制器中执行了 loadingResourceDidFinish loadingResourceDidFinish 在后台发送微调器

- (void)loadingResourceDidFinish:(Feed*)f {
    isReloading = NO;
    [self loadingResourceDidFinishPostAction];
}
- (void)loadingResourceDidFinishPostAction {
        [self hideMuar];
}
- (void)hideMuar {
    [loadingIndicator stopAnimating];
    [self.view sendSubviewToBack:muar];
}

一切正常,但在 loadingResourceDidFinish 完成后,微调器将被发送到背景大约4秒。

确切地说,muar是一个不透明的UIView,它包含微调器。我只是想在我原来的解释中抽象出复杂性!

我尝试过NSLog这个,听起来好像没有重新绘制,直到reloadData完成。我认为这是一个重新出现的问题,因为如果我在 loadingResourceDidFinish 结束后转向我的iPhone,一切都很好,旋转器消失了。

我尝试删除解析器函数中的NSAutoreleasePool,但不会更改。

我肯定误解了一些东西,但我不知道它是什么......


修改

我更改了代码以减少混乱。 UITableView的reloadData现在放在这里:

- (void)loadingResourceDidFinishPostAction {
    [tableView reloadData];
    [self hideMuar];
    NSLog(@"loadingResourceDidFinishPostAction end");
}

对于调试:

- (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"cellForRowAtIndexPath %i", indexPath.row);
        ...

那么为什么第一个单元格在loadResourceDidFinishPostAction结束后仅重新绘制了5秒?

2010-09-02 10:15:35.279 myapp[9632:5b03] loadingResourceDidFinishPostAction end
2010-09-02 10:15:40.208 myapp[9632:5b03] cellForRowAtIndexPath 0
2010-09-02 10:15:40.697 myapp[9632:5b03] cellForRowAtIndexPath 1
2010-09-02 10:15:40.878 myapp[9632:5b03] cellForRowAtIndexPath 2

我的iPhone 3G和iPhone 4模拟器也是如此。

2 个答案:

答案 0 :(得分:31)

我不确定是什么导致了你的延迟,但它闻起来可能是一个线程问题。许多UIKit类都不是线程安全的。作为一般规则,您应该尝试确保所有UI交互都发生在主线程上。在您最初发布的代码中,看起来您正在从后台线程调用reloadData,这似乎有风险。我不清楚从现在开始调用哪个线程你已经改变了你的代码。

浏览您的doUpdate代码路径,确保通过performSelectorOnMainThread:完成任何可能导致UI更新的代理回复。

答案 1 :(得分:0)

以下是我编辑问题的新答案。

我不确切知道发生了什么,因为通常情况下,表视图会重新加载数据并在不会运行缓慢的单独线程中重绘表视图。以下是您可以查看的猜测:

1 /检查您是否正确地重复使用单元格标识符

2 /检查是否有任何其他数据源和委托方法在

中执行繁重的网络工作
* – tableView:cellForRowAtIndexPath:  required method
* – numberOfSectionsInTableView:
* – tableView:numberOfRowsInSection:  required method

或在:

#  – tableView:heightForRowAtIndexPath:
# – tableView:indentationLevelForRowAtIndexPath:
# – tableView:willDisplayCell:forRowAtIndexPath: