Ошибка GMMGeoTileImageData с MapKit - PullRequest
       2

Ошибка GMMGeoTileImageData с MapKit

1 голос
/ 08 марта 2012

В моем viewcontroller я использую Карты и загружаю список пинов.Когда я перемещаю карту или увеличиваю или уменьшаю ее, мое приложение вылетает и отображает эту ошибку:

[GMMGeoTileImageData isEqualToString:]: unrecognized selector sent to instance 0x862d3b0

Это мой код контроллера представления:

    - (void)viewDidLoad
    {

        statoAnn = [[NSMutableString alloc] initWithFormat:@"false"];

        //bottone annulla per tornare indietro
        UIBarButtonItem *annullaButton = [[[UIBarButtonItem alloc] initWithTitle:@"Annulla" style:UIBarButtonItemStylePlain target:self action:@selector(backView)] autorelease];
        self.navigationItem.leftBarButtonItem = annullaButton;


        //inizializzo la mappa
        mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, 320, 416)];
        mapView.delegate = self;
        mapView.mapType = MKMapTypeStandard;
        [self.view addSubview:mapView];

        [self setGmaps:arrData];

        [super viewDidLoad];
    }


/** inizializzo l'annotation del poi mappa **/
- (void) setGmaps:(NSMutableArray*)inputData { 

    // setto la lat e lng 
    CLLocationDegrees latitude;
    CLLocationDegrees longitude;
    CLLocationCoordinate2D poiLocation;
    arrAnn = [[NSMutableArray alloc] init];

    for(int i=0; i<[inputData count]; i++) {

        //ricavo la lat e lng del pin
        latitude  = [[[inputData objectAtIndex:i] objectForKey:@"latitude"]  doubleValue];
        longitude = [[[inputData objectAtIndex:i] objectForKey:@"longitude"] doubleValue];

        // setto la location del poi
        poiLocation.latitude = latitude;
        poiLocation.longitude = longitude;
        //[[[CLLocation alloc] initWithLatitude:latitude longitude:longitude] autorelease];

        //setto il pin
        Annotation *ann = [[Annotation alloc] initWithCoordinate:poiLocation];
        ann.title = [[inputData objectAtIndex:i] objectForKey:@"label"];
        [arrAnn addObject:ann];
        [ann release]; 

    }


    if (nil != self.arrAnn) {

        [self.mapView addAnnotations:arrAnn];
        //self.ann = nil;
        self.arrAnn = nil;
    }

}

/** setto il pin nella mappa ***/
- (void)setCurrentLocation:(CLLocation *)location {

    MKCoordinateRegion region = {{0.0f, 0.0f}, {0.0f, 0.0f}};

    region.center = location.coordinate;

    region.span.longitudeDelta = 0.1f;
    region.span.latitudeDelta  = 0.1f;

    [self.mapView setRegion:region animated:YES];
    [self.mapView regionThatFits:region];
}


- (MKAnnotationView *)mapView:(MKMapView *)mapViewTemp viewForAnnotation:(id <MKAnnotation>)annotation {

    MKPinAnnotationView *view = nil; // return nil for the current user location

        view = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"identifier"];

        if (nil == view) {
            view = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"identifier"] autorelease];
            view.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
        }

        [view setPinColor:MKPinAnnotationColorPurple];
        [view setCanShowCallout:YES];
        [view setAnimatesDrop:YES];

    if (![statoAnn isEqualToString:@"true"]) {
        CLLocation *location = [[CLLocation alloc] initWithLatitude:annotation.coordinate.latitude
                                                          longitude:annotation.coordinate.longitude];
        [self setCurrentLocation:location];
        statoAnn = [NSMutableString stringWithFormat:@"true"];
    } 


    return view;
}

1 Ответ

2 голосов
/ 08 марта 2012

В viewForAnnotation, эта строка:

statoAnn = [NSMutableString stringWithFormat:@"true"];

устанавливает statoAnn в автоматически освобожденную строку.

Когда метод завершается, вызывается release на statoAnn, и он больше не владеет памятью, на которую он указывал. Когда метод вызывается снова при масштабировании или перемещении карты, память, на которую указывал statoAnn, теперь используется чем-то другим (GMMGeoTileImageData в данном случае). Этот объект не является NSString и не имеет метода isEqualToString:, и вы получаете сообщение об ошибке.

Чтобы исправить это, установите statoAnn, чтобы значение сохранялось, как вы делаете в viewDidLoad. Например, вы можете изменить его на:

statoAnn = [[NSMutableString alloc] initWithFormat:@"true"];

Вы также можете объявить statoAnn как свойство (@property (nonatomic, copy) NSString *statoAnn) и просто установить его, используя self.statoAnn = @"true";. Установщик недвижимости сделает сохранение за вас.


Однако вам не нужно использовать строку для хранения значений «истина» и «ложь». Гораздо проще и эффективнее использовать простой BOOL, и вам не придется беспокоиться о сохранении / освобождении, поскольку это примитивный тип, а не объект.


Другое дело, что viewForAnnotation не является подходящим местом для установки region вида карты в первую очередь. Вы можете сделать это в viewDidLoad после добавления аннотаций.


Еще одна вещь: в верхней части viewForAnnotation у вас есть комментарий «вернуть ноль для текущего местоположения пользователя», но этот код этого не делает. Он просто инициализирует вид на nil. Чтобы действительно сделать то, что говорится в комментарии, вам нужно это:

MKPinAnnotationView *view = nil; 

// return nil for the current user location...
if ([annotation isKindOfClass:[MKUserLocation class]])
    return nil;


Наконец, если dequeueReusableAnnotationViewWithIdentifier действительно возвращает представление (если view! = Nil), вам нужно установить view.annotation для текущей аннотации, так как повторно использованный вид мог быть для другой аннотации.

...