我遇到了一个 bug。我在我的 map 中使用 OSM 瓦片,因为它们能更好地显示我的位置。所以,我的 viewDidLoad
是:
[super viewDidLoad];
self.mapView.delegate = self;
self.searchBar.delegate = self;
self.title = @"Select Location";
NSString *template = @"http://tile.openstreetmap.org/{z}/{x}/{y}.png";
MKTileOverlay *overlay = [[MKTileOverlay alloc] initWithURLTemplate:template];
overlay.canReplaceMapContent = YES;
[self.mapView addOverlay:overlay level:MKOverlayLevelAboveLabels];
self.locationManager = [[CLLocationManager alloc] init];
if ( [CLLocationManager locationServicesEnabled] ) {
self.locationManager.delegate = self;
self.locationManager.distanceFilter = 1000;
[self.locationManager startUpdatingLocation];
}
self.geocoder = [[CLGeocoder alloc] init];
...
好吧,错误出现了,当我尝试按返回键或选择当前位置图钉时(我上面有一个 UIButton,在 View 的所有图 block 加载之前。
我检查过this问题。并添加了这个:
- (void)viewWillDisappear:(BOOL)animated {
self.mapView = nil;
[super viewWillDisappear:animated];
}
我尝试在 viewWillDisappear
和 dealloc
中使用这段代码,但似乎都不起作用。接下来,我已经覆盖了后退按钮操作,但仍然有这个问题:
- (void)viewWillDisappear:(BOOL)animated {
if ([self.navigationController.viewControllers indexOfObject:self] == NSNotFound) {
self.locationManager.delegate = nil;
self.mapView = nil;
self.searchBar.delegate = nil;
[self.navigationController popViewControllerAnimated:YES];
}
[super viewWillDisappear:animated];
}
据我所知,EXC_BAD_ACCESS 通常出现在某些东西试图访问该对象时,当它已准备好被释放时。
如何正确释放所有数据?
更新:
异常出现在线上:
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
它出现在第一个线程中:
libobjc.A.dylib`objc_msgSend:
0x3b172620: cbz r0, 0x3b17265e ; objc_msgSend + 62
0x3b172622: ldr.w r9, [r0]
0x3b172626: ldrh.w r12, [r9, #12] <<<< Here
最后在 UIApplicationMain 中
0x3316e148: blx 0x33731cc4 ; symbol stub for: CFRunLoopSourceSignal$shim
0x3316e14c: movs r0, #0x0 <<< This line
UPD2: 好吧,在模拟器上运行僵尸并检查堆栈显示了这样的东西:
据我了解,当 MKTileOverlay 尝试在已释放的 MapView 上加载图 block 时,问题就出现了。如何解决这个问题?
最佳答案
嗯,看来我找到了解决办法。
来源来自here .
我已经做了两个修复。首先,我将所有的图 block 处理移到了异步 block 中:
dispatch_async(dispatch_get_main_queue(), ^{
NSString *template = @"http://tile.openstreetmap.org/{z}/{x}/{y}.png";
MKTileOverlay *overlay = [[MKTileOverlay alloc] initWithURLTemplate:template];
overlay.canReplaceMapContent = YES;
[self.mapView addOverlay:overlay level:MKOverlayLevelAboveLabels];});
接下来,我将这一行添加到 dealloc
并删除了 viewWillDisappear
:
- (void)dealloc
{
[self.mapView removeOverlays:[self.mapView overlays]];
}
现在看来可以了。
关于ios - 在加载图 block 之前从 MapView 退出时的 EXC_BAD_ACCESS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24875060/