Фон: У меня есть список контактов, которые извлекаются в асинхронной очереди из базы данных, основанной на облаке. После этого я отправлю обратно в основную очередь и покажу эти контакты в TableView.Преобразование асинхронно большого количества данных GPS в город/страну
Помимо имен и других деталей, каждый контактный объект имеет свойства координат GPS (широта и долгота). Я хочу использовать эти координаты GPS для извлечения имени города и страны каждого контакта и обновления TableView, отображающего эту информацию на локальном языке устройства, которое пользователь имеет.
Проблема: Проблема, которую я пытаюсь преодолеть, состоит в том, что у меня есть несколько сотен контактов. Сначала я использовал параллельные очереди для получения строк города/страны. Но я приостановил приложение в XCode и понял, что создано 300 новых потоков. Поэтому я изменил код, запускающий каждый поиск в городе/стране в той же последовательности.
Проблема в том, что только около 50 контактов данные обновляются. Я не знаю, почему и не уверен, даже если очередь последовательна. Отладка показывает, что все еще создано более 100 серийных очередей. В тот момент я ожидал одного. Что я делаю не так? Благодаря
код для класса, в котором у меня есть TableView выглядит следующим образом:
dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.rawValue), 0)) {
// get or update the contactsList
activeUser.contactsList.getAllContacts()
// once we have the contacts we go back to the main queue
dispatch_async(dispatch_get_main_queue()) {
// and refresh tableview to show the contacts
self.tableView.reloadData()
// now we refresh the locations of the contacts
for index in 0...activeUser.contactsList.listOfContacts.count
{
// set local variables for lat and long
let lat = activeUser.contactsList.listOfContacts[index].latitude
let long = activeUser.contactsList.listOfContacts[index].longitude
// call location service method with completion handler
MyLocationServices().updateLocationToLocalLanguage(lat, longitude: long, completionHandler:
{ (city, country) ->() in
// update contact's details
activeUser.contactsList.listOfContacts[index].city = city
activeUser.contactsList.listOfContacts[index].country = country
// refresh each time the table to show updated contact data
self.tableView.reloadData()
})
}
}
метод в классе MyLocationServices выглядит следующим образом:
func updateLocationToLocalLanguageDispatched(latitude: String, longitude: String, completionHandler: (city: String, country: String) ->())
{
let serialQ = dispatch_queue_create("AddressUpdateQ", DISPATCH_QUEUE_SERIAL)
dispatch_async(serialQ)
{
var cityString = "NA"
var countryString = "NA"
let group = dispatch_group_create()
dispatch_group_enter(group)
let location = CLLocation(latitude: Double(latitude)!, longitude: Double(longitude)!)
self.geocoder.reverseGeocodeLocation(location)
{
(placemarks, error) -> Void in
if let placemarks = (placemarks as [CLPlacemark]!) where placemarks.count > 0
{
let placemark = placemarks[0]
if ((placemark.addressDictionary!["City"]) as? String != nil) { cityString = ((placemark.addressDictionary!["City"]) as? String)! }
if ((placemark.addressDictionary!["Country"]) as? String != nil) { countryString = ((placemark.addressDictionary!["Country"]) as? String)! }
}
dispatch_group_leave(group)
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER)
dispatch_async(dispatch_get_main_queue())
{
completionHandler(city: cityString, country: countryString)
}
}
}