我在ViewController類中有一個UITableView。 ViewController類使用自定義的dataController(在AppDelegate中指定)。在dataController類中,我從Web中獲取一些JSON,將其解析爲NSMutableArray,然後使用該數據在ViewController中填充UITableView。從獨立的DataController類使用宏中央調度在ViewController類中填充UITableView
這一切都很好,除非應用程序啓動時有明顯的延遲,因爲需要時間才能獲取JSON並使用它。我想在加載這些數據時顯示一個帶有活動指示符的空UITableView。不幸的是,只要我把dataController類中的代碼放入一個調度隊列中,UITableView就不會填充數據(數據根據日誌加載)。我看到的只是一張空白的桌子。
我想我的主要問題是我不知道如何在dataController類中設置隊列,然後使用該隊列中的數據更新UI,但在另一個類中。
相關的代碼:
從DataController類類:
- (void)initializeDefaultDataList {
NSMutableArray *dataList = [[NSMutableArray alloc] init];
self.masterDataList = dataList;
dispatch_queue_t myQueue = dispatch_queue_create("name.queue.my", NULL);
dispatch_async(myQueue, ^{
NSString *jsonString = [JSONHelper JSONpostString:@"http://webservice/getData"];
NSError *jsonError = nil;
//convert string to dictionary using NSJSONSerialization
NSDictionary *jsonResults = [NSJSONSerialization JSONObjectWithData: [jsonString dataUsingEncoding:NSUTF8StringEncoding]
options: NSJSONReadingMutableContainers
error: &jsonError];
if (jsonError) NSLog(@"[%@ %@] JSON error: %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), jsonError.localizedDescription);
NSArray *dataArray = [jsonResults objectForKey:@"d"];
for (NSString *dataItem in dataArray) {
[self addDataWithItem:dataItem];
}
});
}
從AppDelegate中:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
MyMasterViewController *firstViewController = (MyMasterViewController *)[[navigationController viewControllers] objectAtIndex:0];
MyDataController *aDataController = [[MyDataController alloc] init];
firstViewController.dataController = aDataController;
return YES;
}
從視圖控制器:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
//would this go here?
dispatch_async(dispatch_get_main_queue(), ^{
MyObject *objectAtIndex = [self.dataController objectInListAtIndex:indexPath.row];
[[cell textLabel] setText:objectAtIndex.name];
});
return cell;
}
如果你不能說我對iOS和Objective C真的很陌生,任何幫助或暗示,你可以給予不勝感激。我甚至不確定我是否正確地表達了我的問題 - 看起來我想要做的事情不應該這麼困難。謝謝!
編輯
好了,也許這是一個生命週期的問題。剛剛意識到,我在異步塊內設置的任何內容在塊之外都是零,至少直到它爲時已晚才能起作用。這就是爲什麼cellForRowAtIndexPath永遠不會被調用 - 因爲傳遞給UITableView的masterDataList是空的。通過初始化
__block NSString *s = [[NSString alloc] init];
塊之外,則塊內設置一個值測試此:
s = @"Testing...";
最後NSLogging s的值的塊具有假想運行之後。但顯然該塊還沒有運行,因爲s是零。
我想,在視圖控制器,但它可能不在正確的位置。那會在viewDidLoad方法,cellForRowAtIndexPath方法或其他地方完成嗎? – esvendsen 2012-03-19 00:19:14
+1爲reloadData提示。雖然這不是我的問題的完整答案,但它絕對是不可或缺的。 – esvendsen 2012-03-27 12:46:53