我一直在使用MKMapView时遇到内存泄漏的问题(已向苹果报告,但未得到回复),因此我尝试了一个解决方法,即只分配一个MKMapView并重复使用该地图,而不是重新分配一个新的地图。但是,我遇到的问题是我无法将MKMapView重置为其起始视图。我认为这是因为我最初在美国工作,所以我最初看到的视图类似于:
(来源:cprince.com)。使用以下代码:
当我点击调用annotateMap的按钮时,我会得到以下地图(目前没有惊喜):![map of my home](https://istack.dev59.com/aS0gu.webp)
(来源:cprince.com) 然后,当我从此视图导航离开(使用导航控制器),再次进入视图(viewWillAppear再次被调用,但这次它重新使用先前分配的MKMapView),我会得到以下地图视图:![map of ocean](https://istack.dev59.com/AW8DQ.webp)
(来源:cprince.com) 当然,由于viewWillAppear的这部分代码,我应该得到原始的默认区域:
无论是在addSubview之前还是之后进行setRegion都没有关系。也就是说,下面的更改不能解决问题:
问题也不是由于MKMapView中的某种竞态条件引起的。如果我更改按钮的处理程序:
![map of USA](https://istack.dev59.com/bsOaw.webp)
static MKMapView *map = nil;
- (void) showUserLocation {
[map setShowsUserLocation:YES];
CLLocationCoordinate2D coord;
coord.latitude = 39.0; // changed from original coords
coord.longitude = -105.0;
MKCoordinateRegion r = MKCoordinateRegionMakeWithDistance(coord, 1000, 1000);
[map setRegion:r animated:YES];
}
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (! map) {
CGRect r = CGRectMake(20, 50, 196, 75);
map = [[MKMapView alloc] initWithFrame:r];
defaultRegion = MKCoordinateRegionMake(map.centerCoordinate, MKCoordinateSpanMake(180, 360));
} else {
[map setRegion:defaultRegion animated:YES];
}
[self.view addSubview:map];
}
- (IBAction)annotateMap:(id)sender {
[self showUserLocation];
}
当我点击调用annotateMap的按钮时,我会得到以下地图(目前没有惊喜):
![map of my home](https://istack.dev59.com/aS0gu.webp)
(来源:cprince.com) 然后,当我从此视图导航离开(使用导航控制器),再次进入视图(viewWillAppear再次被调用,但这次它重新使用先前分配的MKMapView),我会得到以下地图视图:
![map of ocean](https://istack.dev59.com/AW8DQ.webp)
(来源:cprince.com) 当然,由于viewWillAppear的这部分代码,我应该得到原始的默认区域:
defaultRegion = MKCoordinateRegionMake(map.centerCoordinate, MKCoordinateSpanMake(180, 360));
} else {
[map setRegion:defaultRegion animated:YES];
}
无论是在addSubview之前还是之后进行setRegion都没有关系。也就是说,下面的更改不能解决问题:
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
BOOL firstTime = NO;
if (! map) {
firstTime = YES;
CGRect r = CGRectMake(20, 50, 196, 75);
map = [[MKMapView alloc] initWithFrame:r];
defaultRegion = MKCoordinateRegionMake(map.centerCoordinate, MKCoordinateSpanMake(180, 360));
}
[self.view addSubview:map];
if (! firstTime) {
[map setRegion:defaultRegion animated:YES];
}
}
使用MKMapRectWorld也没有帮助:
defaultRegion = MKCoordinateRegionForMapRect(MKMapRectWorld);
问题也不是由于MKMapView中的某种竞态条件引起的。如果我更改按钮的处理程序:
- (IBAction)annotateMap:(id)sender {
defaultRegion = MKCoordinateRegionMake(map.centerCoordinate, MKCoordinateSpanMake(180, 360));
[self showUserLocation];
}
当地图停留在美国视图上并且在我点击按钮之前等待,问题仍然存在。
我使用的是iOS 6.1.2和XCode 4.6。
(完整的XCode项目可在http://www.cprince.com/stackoverflow/Map.zip中找到)。
您有什么想法?
第一次更改:
我将defaultRegion从实例变量更改为静态变量,但这并没有显著改变情况。(我在下面报告了默认区域的经纬度)。以下是地图上的结果:
(来源:cprince.com)
为了清晰起见,现在的代码如下:
static MKMapView *map = nil;
static MKCoordinateRegion defaultRegion;
- (void) showUserLocation {
[map setShowsUserLocation:YES];
CLLocationCoordinate2D coord;
coord.latitude = 39.0; // changed from original
coord.longitude = -105.0;
MKCoordinateRegion r = MKCoordinateRegionMakeWithDistance(coord, 1000, 1000);
[map setRegion:r animated:YES];
}
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
BOOL firstTime = NO;
if (! map) {
firstTime = YES;
CGRect r = CGRectMake(20, 50, 196, 75);
map = [[MKMapView alloc] initWithFrame:r];
defaultRegion = MKCoordinateRegionMake(map.centerCoordinate, MKCoordinateSpanMake(180, 360));
NSLog(@"defaultRegion: center: lat: %f, long: %f; span: %f dlat: dlong: %f", defaultRegion.center.latitude, defaultRegion.center.longitude, defaultRegion.span.latitudeDelta, defaultRegion.span.longitudeDelta);
//defaultRegion = MKCoordinateRegionForMapRect(MKMapRectWorld);
}
[self.view addSubview:map];
if (! firstTime) {
NSLog(@"defaultRegion: center: lat: %f, long: %f; span: %f dlat: dlong: %f", defaultRegion.center.latitude, defaultRegion.center.longitude, defaultRegion.span.latitudeDelta, defaultRegion.span.longitudeDelta);
[map setRegion:defaultRegion animated:YES];
}
}
- (IBAction)annotateMap:(id)sender {
//defaultRegion = MKCoordinateRegionMake(map.centerCoordinate, MKCoordinateSpanMake(180, 360));
[self showUserLocation];
}