willSelectRowAtIndexPath / didSelectRowAtIndexPath混淆

时间:2010-10-09 20:45:21

标签: iphone uitableview spinner

这应该很简单: 当调用didSelectRowAtIndexPath时,我运行一个复杂的方法,它下载URL的内容,解析它,并将结果放在各种属性中。 在模拟器中,在WiFi情况下的设备上,一切都很好。但是,在较慢网络上的设备上,只需要一些时间来处理这一切。 因此,我想在所选行的单元格中显示一个微调器,以便让用户感觉到某些事情正在发生。

我的问题是,在选择行的视图和后续视图之间的动画过渡期间,似乎只显示微调器。

我希望微调器在下载,解析和动画期间显示。

我试过了:

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
 myCustomCell = (MyCustomCell*)[tableView cellForRowAtIndexPath:indexPath];
 [myCustomCell.spinner startAnimating];
 return indexPath;
 }

- (NSIndexPath *)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
 myCustomCell = (EventCell*)[tableView cellForRowAtIndexPath:indexPath];
 [myCustomCell.spinner startAnimating];
 [self myVerySlowMethod];
 return indexPath;
 }

然而,旋转器似乎只显示在两个视图之间。

我在Real Device上测试了这个,我从来没有让微调器显示出来。

这是:

a)因为myVerySlowMethod足够快? b)因为didSelectRowAtIndexPath将首先处理所有内容,然后执行显示部分或 c)在我打扰你之前,我应该学习所有精心编写的编程指南吗?

感谢任何回答。

1 个答案:

答案 0 :(得分:1)

问题是在这两种情况下,你的[self myVerySlowMethod](或等效的)都阻塞了主线程,因此ActivityIndi​​cator不会播放。

最好的方法是在后台线程上运行myVerySlowMethod,然后在完成后调用另一个将新视图控制器推送到导航堆栈的方法。

首先,调用方法在后台运行:

[self performSelectorInBackground:(@selector(myVerySlowMethod)) withObject:nil];

这将自动创建一个新的后台线程供您运行。然后,您必须确保在后台方法中执行以下操作:

-(void) myMethod {
   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   // code you want to run in background thread;
   [pool drain];
}

这是必要的,因为没有为除主要线程之外的任何线程设置默认自动释放池。

最后,您需要将新视图控制器推送到主线程上的导航堆栈中。如果您有另一种方法,请从后台线程中调用它,如下所示:

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

如果你想在其后做其他事情,可选的第三个参数将为你提供主线程。

希望有所帮助!