EXC_BAD_ACCESS при попытке прочитать свойство, установленное CLLocation newLocation - PullRequest
1 голос
/ 06 октября 2011

Итак, у меня есть объект модели, который называется «местоположение» и имеет набор свойств. Одним из которых является ' distanceFromUserLocation '. Очевидно, что для этого нужно знать местоположение пользователя, поэтому в объекте модели я вычисляю текущее местоположение пользователя.

Это также устанавливает свойство CLLocation для этой модели каждый раз при использовании метода didUpdateToLocation.

У меня также есть метод initWithDictionary в модели, который устанавливает все значения для свойств в модели местоположения.

код ниже для моей модели:

@synthesize name = _name;
@synthesize entryLocation = _entryLocation;
@synthesize address = _address;
@synthesize contactNumber = _contactNumber;
@synthesize distanceFromUserLocation = _distanceFromUserLocation;
@synthesize itemDescription = _itemDescription;
@synthesize locationManager = _locationManager;
@synthesize userLocation = _userLocation;


-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation        *)newLocation fromLocation:(CLLocation *)oldLocation
{
    if (newLocation != nil) {
        self.userLocation = newLocation;
        NSLog(@"lat: %@ lon: %@ ", [NSString stringWithFormat:@"%.7f",   newLocation.coordinate.latitude], [NSString stringWithFormat:@"%.7f", newLocation.coordinate.longitude]);
    }

    [manager stopUpdatingLocation];
}

-(id)initWithDictionary:(NSDictionary*) dictionary
{
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;

    [self.locationManager startUpdatingLocation];

    self = [super init];
    if (self) 
    {
        self.name = [dictionary valueForKey:@"Name"];
        self.address = [dictionary valueForKey:@"Address"];
        self.contactNumber = [dictionary valueForKey:@"ContactNumber"];
        self.itemDescription = [dictionary valueForKey:@"Description"];
        double lat = [[dictionary valueForKey:@"Latitude"] doubleValue];
        double lon = [[dictionary valueForKey:@"Longitude"] doubleValue];
        self.entryLocation = [[CLLocation alloc] initWithLatitude:lat longitude:lon];
        self.distanceFromUserLocation = [self.userLocation distanceFromLocation:self.entryLocation];
    }

    return self;
}

Проблема, с которой я столкнулся, заключается в том, что в didUpdateToLocation я устанавливаю для свойства self.currentLocation значение newLocation . Затем я записываю lat и long, чтобы убедиться, что у меня действительно есть значение, которое я делаю.

Однако, когда я затем инициализирую экземпляр модели 'Location' из моего класса контроллера, а затем записываю значение currentLocation для этого объекта модели:

NSLog(@"%@", location.currentLocation);

Я получаю (ноль) в журнале.

Если я попробую:

NSLog(@%@", location.currentLocation.coordinate.latitude);

Я получаю EXC_BAD_ACCESS ошибку.

Я успешно получаю текущее местоположение в didUpdateToLocation и регистрирую его, но почему тогда, когда я устанавливаю для свойства currentLocation значение newLocation, оно не сохраняется?

Любая помощь с этим будет принята с благодарностью:)

Ответы [ 3 ]

0 голосов
/ 06 октября 2011

Значения, отправляемые на locationManager:didUpdateToLocation:fromLocation: (надеюсь, вы используете его, а не менее надежный метод делегата MKMapView), не очень надежны. Теоретически, вы должны получить последовательный выбор постепенно более точных значений. Однако часто отправляется нулевое значение, как вы заметили и проверяете в своем коде; но координата 0.0,0.0 также часто отправляется, и вы должны проверить и проигнорировать это. Также рекомендуется проверить свойства horizontalAccuracy и verticalAccuracy на наличие отрицательных значений и отклонить эти CLLocation s.

0 голосов
/ 10 октября 2011

Таким образом, оказывается, что ошибка EXC_BAD_ACCESS была до того, что предложили joost и JBat100. Просто использовать% @ вместо% f. Однако я выяснил, почему я не смог получить значение местоположения пользователя из свойства на контроллере. Методы вызываются асинхронно, а метод forRowAtIndexPath рендерил ячейки таблицы ПЕРЕД тем, когда можно было найти местоположение пользователя, поэтому при вызове указатель на местоположение пользователя ничего не указывал.

Я решил это, добавив представление с индикатором активности, которое находит местоположение пользователя, сохраняет его в свойстве, а затем помещает представление с таблицей на экран, устанавливая его свойство userlocation таким образом, чтобы свойство никогда не было пусто:)

Спасибо за помощь всем!

0 голосов
/ 06 октября 2011
location.currentLocation.coordinate.latitude

имеет тип CLLocationDegrees, который определен как

typedef double CLLocationDegrees;

. Вы можете использовать% @ только с экземплярами класса, которые наследуются от NSObject (вообще говоря).Вы должны распечатать двойное число, например:

NSLog(@"%f", location.currentLocation.coordinate.latitude);

При использовании метода доступа

self.userLocation = newLocation;

значение сохраняется, если свойство указано как retain.

...