objective c - GMMGeoTileImageData error with MapKit -
in viewcontroller use maps , load list of pins. when move map or zoom in or out it, app crashes , displays error:
[gmmgeotileimagedata isequaltostring:]: unrecognized selector sent instance 0x862d3b0 this code of view controller:
- (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 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; }
in viewforannotation, line:
statoann = [nsmutablestring stringwithformat:@"true"]; sets statoann autoreleased string.
when method exits, release called on statoann , no longer owns memory pointing to. when method called again when zoom or move map, memory statoann pointing used else (gmmgeotileimagedata in case). object not nsstring , doesn't have isequaltostring: method , error seeing.
to fix this, set statoann value retained doing in viewdidload. example, change to:
statoann = [[nsmutablestring alloc] initwithformat:@"true"]; you declare statoann property (@property (nonatomic, copy) nsstring *statoann) , set using self.statoann = @"true";. property setter retaining you.
however, don't need use string hold "true" , "false" value. it's easier , efficient use plain bool , won't have worry retain/release since it's primitive type , not object.
other thing viewforannotation not right place setting map view's region in first place. can in viewdidload after annotations added.
thing: @ top of viewforannotation, have comment "return nil current user location" code doesn't that. initializes view nil. comment says, need this:
mkpinannotationview *view = nil; // return nil current user location... if ([annotation iskindofclass:[mkuserlocation class]]) return nil;
finally, if dequeuereusableannotationviewwithidentifier return view (if view != nil), need set view.annotation current annotation since re-used view may have been different annotation.
Comments
Post a Comment