Ожидать асинхронный обратный вызов - 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, но эта структура находится в стеке. Как только этот метод вернется, содержимое указанной структуры будет уничтожено.

Другие вопросы по тегам