Вопрос о делегировании в Objective-C, CLLocationManager - PullRequest
0 голосов
/ 03 апреля 2011

Я немного запутался, как работает делегирование.Я считаю, что идея состоит в том, чтобы другой класс сделал работу за вас и перезвонил вам.Так что, если вы сделали что-то вроде этого:

- (void)viewDidLoad {
    [super viewDidLoad];
    locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    locationManager.desiredAccuracy = kCLLocationAccuracyBest;

    if (CLLocationManager.locationServicesEnabled == YES) {
        NSLog(@"location enabled");
        latitudeLabel.text = [NSString stringWithFormat:@""];
        [locationManager startUpdatingLocation];
    }
    NSLog(@"%g", locationCoordinate.latitude);
}

Если я NSLog координату в viewDidLoad, даже если я startUpdatingLocation, значение моего свойства locationCoordinate равно 0. Но если я NSLog значение в методе делегатавот так:

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
    NSString *latitudeString = [[NSString alloc] initWithFormat: @"%g m", newLocation.coordinate.latitude];
    latitudeLabel.text = latitudeString;
    [latitudeString release];
    locationCoordinate = newLocation.coordinate;
    NSLog(@"in delegate: %g", locationCoordinate.latitude);
}

Я получаю фактическое значение местоположения.Я думал, что с помощью метода делегата, мой locationProperty будет установлен, но, похоже, нет.Я неправильно понимаю делегирование?Спасибо.

Ответы [ 4 ]

0 голосов
/ 03 апреля 2011

Чтобы понять, что здесь происходит, вы должны сначала попытаться понять схему делегирования.Это объектно-ориентированный шаблон, который применяется ко многим языкам:

http://en.wikipedia.org/wiki/Delegation_pattern

В этом случае CLLocationManager выполняет задачу поиска местоположения.Когда это сделано с этой задачей, он знает, что вы, вероятно, хотите что-то сделать с собранной информацией, но он не знает, что именно.Устанавливая «self» в качестве делегата, вы говорите CLLocationManager, что, когда он завершит получение местоположения, вы позаботитесь о том, что будет дальше.Вы делаете это путем реализации метода делегата locationManager.Когда менеджер местоположения завершит поиск местоположения, он вызовет этот метод, но не раньше.В вашем первом NSSLog вы смотрите на широту до того, как менеджер местоположения выяснил, какая это текущая широта.

0 голосов
/ 03 апреля 2011

Единственное, что получает делегирование - это то, что locationManager вызывает ваш метод делегата.Объекты обычно не изменяют свойства своих делегатов.

Таким образом, чтобы быть уверенным, что ваше свойство координат обновлено, вам нужно реализовать метод делегата CLLocationManager так, как вы это делали.На самом деле я бы посоветовал вам вообще не использовать свойство locationCoordinate, а вместо этого использовать свойство locationManager.

0 голосов
/ 03 апреля 2011

Основная причина, по которой существуют делегаты, на самом деле в ситуациях, подобных той, которую вы описываете.

У вас есть некоторые функциональные возможности в классе, но функциональность асинхронная, то есть вы не можете просто получить информацию сразу, или она реализована асинхронно (например, загрузка большого файла из сети должна / делает происходит асинхронно, чтобы не блокировать весь интерфейс в течение минуты +).

Таким образом, используя делегирование, вы можете сказать: «Просто станьте моим делегатом, и я, в конце концов, вернусь к вам, мы уже закончили». Затем объект может вернуться обратно к вызывающей стороне в удобное для него время, а не наоборот (вызывается только тогда, когда этого хочет основное приложение).

Как уже говорилось, загрузка файлов и вот где делегирование вступает в игру. Это также очень полезный инструмент для вашего собственного кодирования для включения делегатов в ваш код, в случаях, когда вам нужно либо ждать делегирования от какого-либо другого объекта (например, CLLocationManager), либо вам нужно что-то обрабатывать на отдельный поток (например, анализ данных или еще много чего).

0 голосов
/ 03 апреля 2011

После того, как вы включите службы определения местоположения, потребуется время, чтобы значения для местоположения были там.Вероятно, поэтому в первом примере вы не получаете результатов.(это и я думаю, что вы должны вызывать метод startUpdatingLocation).
Идея с делегатом здесь заключается в том, что класс, который вы устанавливаете в качестве делегата, более или менее обещает реализовать методы, которые вызывающий может затем вызывать всякий раз, когда HE считает это необходимым,

Как показывает подпись метода во втором примере, Locationmanager - это тот, кто знает о происходящих обновлениях, и делегат позволяет ему затем предпринять действия.Если вы не будете использовать что-то подобное, вам придется периодически запрашивать изменения местоположения

...