2015-07-03 2 views
2

В моем приложении iOS я пытаюсь извлечь данные с сервера. Я хочу сделать это асинхронно. Я пытаюсь это:Как получить данные асинхронно с сервера в iOS и обновить интерфейс после получения данных?

- (void)loadData { 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

    /** code for fetching data. **/ 

    dispatch_async(dispatch_get_main_queue(), ^{ 
    myList = [NSMutableArray arrayWithObjects:fetchedData, nil]; 
    }); 
}); 


} 

Выше метод LoadData() вызывается из метода Init() из tableViewController.

Я использую данные из объектов в этом списке, которые будут отображаться как ячейки. Но прежде чем я получу данные с сервера, основной поток пытается заполнить пользовательский интерфейс из списка (который, очевидно, будет пустым). Как их синхронизировать?

Я обнаружил, что:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 

выше функции (которая возвращает счетчик MyList) возвращает 0, и, следовательно, мой стол отображается как пустой. Эта функция вызывается до того, как я получу данные с сервера (так как это занимает больше времени, в то время как этот метод немедленно передает управление в основной поток).

+0

дайте мне знать, что ваш вопрос закончился – Spynet

ответ

2

После получения данных с сервера просто «перезагрузите» таблицу еще раз. затем методы (numberOfRows, numberOfSections, ...) вызываются снова.

Вызов этого метода для перезагрузки всех данных, которые используются для построения таблицы, включая ячейки, верхние и нижние колонтитулы разделов, массивы индексов и т. Д. Для эффективности в представлении таблицы отображаются только те строки, которые видны. Он корректирует смещения, если таблица сжимается в результате перезагрузки. Делегат табличного представления или источник данных вызывает этот метод, когда он хочет, чтобы представление таблицы полностью перезагрузило свои данные. Он не должен вызываться в методах, которые вставляют или удаляют строки, особенно в блоке анимации, реализованном с вызовами beginUpdates и endUpdates.

Проверить https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableView_Class/index.html#//apple_ref/occ/instm/UITableView/reloadData

- (void)loadData { 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

     /** code for fetching data. **/ 

     dispatch_async(dispatch_get_main_queue(), ^{ 
     myList = [NSMutableArray arrayWithObjects:fetchedData, nil]; 
     yourTable.reloadData() // <-- reload your table after update myList 
     }); 
    }); 


    } 
+0

Точно, что мне нужно! Благодаря! – mb1994

0

Советуем вам проверить AFNetworking (https://github.com/AFNetworking/AFNetworking). В обработчике завершения AFHTTPRequestOperationManager просто настройте tableViewdataSource и delegates и reloadData(). Другим способом является reloadData в методе setter tableView dataSource.

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 
NSString *stringURL = //ur url; 

[manager GET:stringURL parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) { 
    if (completion) { 
     //ur completion 
    } 
} failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
    if (completion) { 
     NSLog(@"error: %@", [error localizedDescription]); 
    } 
}]; 
0
- (void)loadData { 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

/** code for fetching data. **/ 

    dispatch_async(dispatch_get_main_queue(), ^{ 
    myList = [NSMutableArray arrayWithObjects:fetchedData, nil]; 
    [yourTable reloadData]; // reload the data 

    }); 
}); 


} 
+0

спасибо. работал. – mb1994

-1

Вы могли бы хотеть попытаться вызвать вашу функцию LoadData после вызова Youre выборки функции. в сценарии youre loadData вызывается сначала перед функцией fetch, поэтому вы всегда получаете пустой myList. сначала вызовите функцию выборки, прежде чем вы вызове loadData.

Если вы хотите использовать async, вы также можете поместить свою функцию fetch в свой асинхронный режим, но поместите точку останова, чтобы она обычно не вызывала ее.

+0

Я тебя не понял. Я не вызываю loadData() перед функцией fetch. Я вызываю функцию fetch внутри loadData(). Пожалуйста, прочитайте весь вопрос, я уверен, что это будет ясно. – mb1994