Я делал подобные вещи в методе 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
Да, это помогает.