UIView和UITableView,reloadData奇怪的延迟

lef*_*kir 9 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]];
}
Run Code Online (Sandbox Code Playgroud)

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];
}
Run Code Online (Sandbox Code Playgroud)

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

[tableView setDataSource:self];
[tableView reloadData];
Run Code Online (Sandbox Code Playgroud)

一旦doUpdate完成没有错误并且由于我的Operation类,loadResourceDidFinish在我的视图控制器中执行.loadingResourceDidFinish在后台发送微调器.

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

一切正常,但是在loadResourceDidFinish完成后,微调器被发送到背景大约4s .

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

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

我试图在解析器函数中删除NSAutoreleasePool 但不会更改.

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


编辑

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

- (void)loadingResourceDidFinishPostAction {
    [tableView reloadData];
    [self hideMuar];
    NSLog(@"loadingResourceDidFinishPostAction end");
}
Run Code Online (Sandbox Code Playgroud)

并进行调试:

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

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

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
Run Code Online (Sandbox Code Playgroud)

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

cdu*_*uhn 31

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

通过您的doUpdate代码路径,确保通过可以导致UI更新的任何回调给您的代理的调用performSelectorOnMainThread:.

  • 我有同样的问题,但我在ViewController中调用[self.tableView reloadData]!我将此行更改为[self.tableView performSelectorOnMainThread:@selector(reloadData)withObject:nil waitUntilDone:YES]; 并且不再有任何延迟.我太新手解释为什么但它解决了问题!谢谢你们! (2认同)