2012-11-07 70 views
0

我有一個UITableView的問題。我在後臺線程中從數據庫服務器加載數據,如果完成,它會發送通知。在通知中,我更新了我的視圖的數據數組,並在tableview上使用reloadData。 然後tableview取消選擇所選的行(這意味着數據被重新加載),如果我想選擇另一行,我會在didSelectRowAtIndexPath的第一行獲得EXC_BAD_ACCESS,即使它只是一個NSLog。重新加載數據後選擇行崩潰

如果我不分配新數組,後臺線程會將變量數據提供給我並且不使用reloadData我沒有使用didSelectRowAtIndexPath的問題,但tableview不顯示最近的記錄。用戶必須關閉視圖並再次打開以查看更改。這真的很糟糕,我想在後臺線程完成從服務器加載記錄後馬上顯示這些更改。

在.h文件中聲明的變量:

-downloadThread是NSThread,

- 數據是一個NSArray,

-manager是我的SQL接口。

-(void)viewDidLoad 
{ 
    ... 
    [super viewDidLoad]; 
    NSMutableArray *arr = [[manager getTeilnehmerList] retain]; 
    data = arr; 
    [self.tableView reloadData]; 

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(KundenUpdated:) name:@"ContactUpdate" object:nil]; // to be notified when updating thread is finished 

downloadThread = [[NSThread alloc] initWithTarget:self selector:@selector(teilnehmerLoad:) object:nil]; //Thread to get actual data on Background 
[downloadThread performSelector:@selector(start) withObject:nil afterDelay:2]; 
    ... 
} 

-(void)teilnehmerLoad:(id)sender 
{ 
    [manager loadTeilnehmerFromServerAndInsertIntoDatabase]; 
    //data = [manager getTeilnehmerList]; 
    [self.tableView reloadData]; 
    [[NSNotificationCenter defaultCenter] postNotificationName:@"ContactUpdate" object:nil]; 

} 
-(void)KundenUpdated:(NSNotification*)notifaction 
{ 
    @synchronized(self) 
    { 
     //needs function to select row that was selected before reload if the data record is still there after sync with server 
     [self.tableView reloadData]; 
     NSLog(@"count data in kundenupdated: %i",data.count); 
    } 
} 
+0

請在通知方法中發佈代碼? –

+0

那麼你在didSelectRowAtIndexPath的第一行記錄什麼?在cellForRowAtIndexPath中發生了什麼?我懷疑這是你的錯誤所在,可能無法正確回收細胞。 –

+0

請注意,您不應該從後臺調用reloadData(這肯定會導致崩潰),但應該使用peformSelectorOnMainThread或其他方法來使調用在UI線程中執行。 –

回答

0

我懷疑teilnehmerLoad被稱爲在你的後臺線程,它的調用reloadData,這是一個禁忌。

更改它(和/或KundenUpdated)以使用performSelectorOnMainThread來執行reloadData。

確保您沒有從後臺線程中執行任何其他UI操作。

+0

在後臺線程我開始teilnehmerload:如果它完成它發送通知「ContactUpdate」和視圖已添加本身作爲此通知的觀察員,並應啓動kundenUpdated:然後。是kundenUpdated:仍然在後臺線程?我認爲這是在MainThread上,這就是爲什麼假設我可以重新加載數據。如果我使用performSelectorOnMainThread,我應該如何構建它?我寫了[self performSelectorOnMainThread:(KundenUpdated)withObject:nil waitUntilDone:YES];在teilnehmerLoad:現在但我得到一個編譯器錯誤「使用未聲明的標識符'KundenUpdated'」 – Wenduros

+0

確定最後一個問題是我的錯誤閱讀快速;)我忘了@選擇器(kundenUpdated :) – Wenduros

+0

@Wenduros - 我在這個話題上有點弱,但我認爲,默認情況下,通知在通知線程中運行。然而,IIRC有一種方法可以指導它在不同的線程上運行。 –