2011-04-27 48 views
1

我想先顯示視圖,然後在後臺線程中加載數據。當我從根控制器導航到視圖控制器時,我想首先顯示視圖。截至目前,它保持在根控制器上,直到視圖控制器被加載。這是我的根控制器的代碼。iPhone,後臺線程無法正常工作

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

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

[tempProductDetail release]; 
} 

ProductDetailViewController,在這裏我要首先顯示視圖,然後加載數據...

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

-(void) workerThread{ 

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

不知道我做錯了什麼。請幫忙。

+0

performSelectorOnMainThread不創建一個新的thread.detachNewThreadSelector將創建一個新的線程。 – rckoenes 2011-04-27 12:43:28

+0

這樣做 \t [NSThread detachNewThreadSelector:@selector(workerThread)toTarget:self withObject:nil]; 顯示我一個錯誤..... bool _WebTryThreadLock(布爾),0x664e200:試圖從主線程或Web線程以外的線程獲取Web鎖。這可能是從輔助線程調用UIKit的結果。現在崩潰... – donito 2011-04-27 13:55:04

回答

1

發現這個問題的答案,

- (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 
} 
3

使用[self performSelectorInBackground:@selector(workerThread) withObject:nil];,而不是

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

使用這種方法,它告訴我這個錯誤 bool _WebTryThreadLock(布爾),0x6232b10:試圖從主線程或Web線程以外的線程獲取Web鎖。這可能是從輔助線程調用UIKit的結果。立即崩潰... [切換到進程19034] 編程接收信號:「EXC_BAD_ACCESS」。 – donito 2011-04-27 13:45:16

0

考慮使用以下格式而非用於線程,在我看來,這是更清潔:

- (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 
} 

通過這種方式編寫代碼,您可以更動態地決定因爲沒有自動釋放池的要求,所以你想要線程的功能。如果你需要做UI更新,函數將確保它自己在主線程上運行,所以調用者不需要考慮這一點。