开发者

iphone, background thread not working properly

开发者 https://www.devze.com 2023-03-01 13:54 出处:网络
I want to display the view first and then load the data in a background thread. When I navigate from root controller to the view controller, I want to display the view first. As of now, it stays 开发者

I want to display the view first and then load the data in a background thread. When I navigate from root controller to the view controller, I want to display the view first. As of now, it stays 开发者_运维知识库on the root controller until the view controller is loaded. Here's my code for the root controller.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{   
ProductDetailViewController *tempProductDetail = [[ProductDetailViewController alloc] init];

[self.navigationController pushViewController:tempProductDetail animated:YES];

[tempProductDetail release];
}

ProductDetailViewController, here I want to display the view first and then load the data...

- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:YES];
[self performSelectorOnMainThread:@selector(workerThread) withObject:nil waitUntilDone:NO];
}

-(void) workerThread{

NSAutoreleasePool *arPool = [[NSAutoreleasePool alloc] init];
[arPool release];
}

Don't know what I'm doing wrong. Please, help.


Use [self performSelectorInBackground:@selector(workerThread) withObject:nil]; instead of

[self performSelectorOnMainThread:@selector(workerThread) withObject:nil waitUntilDone:NO];


found the answer for this issue,

- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:YES];
[self performSelectorInBackground:@selector(workerThread) withObject:nil];
}

- (void) workerThread
{
// Set up a pool for the background task.
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

// only do data fetching here, in my case from a webservice.
//...

// Always update the components back on the main UI thread.
[self performSelectorOnMainThread:@selector(displayView) withObject:nil waitUntilDone:YES];

[pool release];
}

// Called once the background thread task has finished.
- (void) displayView
{
//here in this method load all the UI components
}


Consider using the following pattern instead for threading, in my opinion it's much cleaner:

- (void)viewWillAppear:(BOOL)animated 
{
   NSInvocationOperation *operation = [[NSInvocationOperation alloc] 
                                       initWithTarget:self 
                                       selector:@selector(someFunction) 
                                       object:nil];
   [[NSOperationQueue currentQueue] addObject:operation]; // this will actually start the thread
   [operation release];
}

- (void)someFunction 
{
   // don't need to initialize and release an autorelease pool here,
   // you can just write a function as usual ...

   [self updateUI];
}

- (void)updateUI 
{
   if (![NSThread isMainThread]) // if we need a UI update, force it on main thread
   {
      [self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:YES];
      return;
   } 

   // do UI updates here
}

By writing code in this way, you can more dynamically decide which function you want to thread, since there is no autorelease pool requirement. If you need to do UI updates, the updateUI function will make sure for itself that it's running on the main thread, so the caller doesn't need to take this into account.

0

精彩评论

暂无评论...
验证码 换一张
取 消