我已经在viewDidAppear方法中做了这样的事情。我的代码启动后台任务来加载来自url的数据。它还将后台任务交给一个方法的选择器,以便在完成时调用控制器。这样通知控制器数据已被下载并可刷新。
我不知道这是否是做到这一点的最好办法,但到目前为止,它的工作对我罚款:-)
为了让一些更多的细节,除了方法的选择调用当后台任务已经加载数据时,我也是它在控制器上执行加载的方法的选择器。这种方式后台任务管理正在发生的事情,但视图控制器提供数据特定的代码。
这里有viewDidAppear代码:
- (void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if (reloadData) {
BackgroundTask *task = [[BackgroundTask alloc] initWithMethod:@selector(loadData) onObject:self];
task.superView = self.view.superview;
task.notifyWhenFinishedMethod = @selector(loadFinished);
[task start];
[task release];
}
}
后台任务有一个可选的SuperView,因为这将增加一个新的UIView包含一个活动的指标了。
BackgroundTask.m看起来是这样的:
@implementation BackgroundTask
@synthesize superView;
@synthesize longRunningMethod;
@synthesize notifyWhenFinishedMethod;
@synthesize obj;
- (BackgroundTask *) initWithMethod:(SEL)aLongRunningMethod onObject:(id)aObj {
self = [super init];
if (self != nil) {
self.longRunningMethod = aLongRunningMethod;
self.obj = aObj;
}
return self;
}
- (void) start {
// Fire into the background.
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(execute:)object:nil];
thread.name = @"BackgroundTask thread";
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskFinished:) name:NSThreadWillExitNotification object:thread];
[thread start];
[thread release];
}
- (void) execute:(id)anObject {
// New thread = new pool.
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
if (self.superView != nil) {
busyIndicatorView = [[BusyIndicator alloc] initWithSuperview:self.superView];
[busyIndicatorView performSelectorOnMainThread:@selector(addToSuperView)withObject:nil waitUntilDone:YES];
}
// Do the work on this thread.
[self.obj performSelector:self.longRunningMethod];
if (self.superView != nil) {
[busyIndicatorView performSelectorOnMainThread:@selector(removeFromSuperView)withObject:nil waitUntilDone:YES];
}
[pool release];
}
- (void) taskFinished:(NSNotification *)notification {
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSThreadWillExitNotification object:notification.object];
[self performSelectorOnMainThread:@selector(notifyObject)withObject:nil waitUntilDone:NO];
}
- (void) notifyObject {
// Tell the main thread we are done.
if (self.notifyWhenFinishedMethod != nil) {
[self.obj performSelectorOnMainThread:self.notifyWhenFinishedMethod withObject:nil waitUntilDone:NO];
}
}
- (void) dealloc {
self.notifyWhenFinishedMethod = nil;
self.superView = nil;
self.longRunningMethod = nil;
self.obj = nil;
[super dealloc];
}
@end
最后,我说,我提出了一个活动的指标。我有一个xib,其中包含50%透明的蓝色背景,中间有一个活动指示器。有一个控制器它有这个代码:
@implementation BusyIndicator
@synthesize superView;
@synthesize busy;
- (BusyIndicator *) initWithSuperview:(UIView *)aSuperView {
self = [super initWithNibName:@"BusyIndicator" bundle:nil];
if (self != nil) {
self.superView = aSuperView;
}
return self;
}
- (void) addToSuperView {
// Adjust view size to match the superview.
[self.superView addSubview:self.view];
self.view.frame = CGRectMake(0,0, self.superView.frame.size.width, self.superView.frame.size.height);
//Set position of the indicator to the middle of the screen.
int top = (int)(self.view.frame.size.height - self.busy.frame.size.height)/2;
self.busy.frame = CGRectMake(self.busy.frame.origin.x, top, self.busy.frame.size.width, self.busy.frame.size.height);
[self.busy startAnimating];
}
- (void) removeFromSuperView {
[self.busy stopAnimating];
[self.view removeFromSuperview];
}
- (void) dealloc {
self.superView = nil;
[super dealloc];
}
@end
好的这有助于。
嗨Derek,仍在玩你的解决方案,但必须能够在viewWillAppear方法中实现,因为我必须在执行[super viewWillAppear]之前加载tabledata。当我通过我的测试时会回来。 在此先感谢,iFloh – iFloh 2010-05-16 15:14:54