Ожидать асинхронный обратный вызов - Objective-C
У меня были некоторые проблемы с обратными вызовами CLLocationManager
Каков наилучший способ ожидания асинхронного обратного вызова?
Вот что я в основном хочу сделать:
- (NSString *) getCurrentCity { [self.locationManager startUpdatingLocation]; // Ожидание координаты в обратных вызовах self.geocoder = [MKReverseGeocoder alloc] initWithCoordonate:self.newCoordonate]; [self.geocoder start]; // Ожидание информации с обратными вызовами MKReverse вернуть self.currentCity; } // Методы обратного вызова MKReverseGeocoder и CLLocationManager - (void)locationManager:(CLLocationManager *) менеджер idUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { CLLocationCoordinate2D newCoordonate = newLocation.coordinate; self.currentCoordonate = &newCoordonate; } - (void)reverseGeocoder:(MKReverseGeocoder *) геокодер didFindPlacemark:(MKPlacemark *) метка { self.currentCity = placemark.locality; }
Где self.currentCity и self.newCoordonate - это атрибут моего класса.
Я попробовал некоторые трюки, такие как Thread и / или синхронизированные, но мне не удалось его не вернуть, пока все не закончится.
С наилучшими пожеланиями
2 ответа
Вы не ждете его завершения, вы обрабатываете обновление, когда асинхронный locationmanager:didUpdatefromLocation:
называется. В этом смысл асинхронного программирования.:)
Каждый раз, когда вы блокируете основной поток, ваше приложение перестает отвечать на запросы (в лучшем случае) и будет отброшено системой (то есть уничтожено - в худшем случае).
Для асинхронных API самый простой шаблон - это изолировать все потоки или очереди или любой другой механизм, который вы используете, чтобы перевести работу из основного потока в класс, который по мере необходимости заботится о возвращении в основной поток.
Например, посмотрите на NSFileHandle
, Оно имеет readInBackgroundAndNotify:
метод. Когда используется, NSFileHandle
Экземпляр внутренне создает поток, использует этот поток для чтения всего, что нужно, затем использует что-то вроде performSelectorOnThread:
отправить уведомление потоку - обычно главному потоку - который вызвал readInBackgroundAndNotify:
на первом месте.
Делая это, пользователи класса не должны иметь дело с потоками, но класс не блокирует основной цикл событий.
КСТАТИ:
{
CLLocationCoordinate2D newCoordinate = newLocation.coordinate;
self.currentCoordonate = &newCoordinate;
}
Это совершенно неправильно и верный способ гарантировать крах или неопределенное поведение. &newCoordinate
дает адрес newCoordinate
, но эта структура находится в стеке. Как только этот метод вернется, содержимое указанной структуры будет уничтожено.