ios - 在加载图 block 之前从 MapView 退出时的 EXC_BAD_ACCESS

标签 ios objective-c exception mkmapview exc-bad-access

我遇到了一个 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];
}

我尝试在 viewWillDisappeardealloc 中使用这段代码,但似乎都不起作用。接下来,我已经覆盖了后退按钮操作,但仍然有这个问题:

- (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: 好吧,在模拟器上运行僵尸并检查堆栈显示了这样的东西:stack

据我了解,当 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/

相关文章:

objective-c - 我们如何结合使用 NSThread 和 NSNotification?

iphone - 检查plist是否存在,如果不存在从这里加载

python - 识别python中的特定异常

c++ - 通过引用抛出非常量临时对象

c# - 更新表中的值 : SQLite error. 提供给命令的参数不足

javascript - 检测 UIWebView 中的 Javascript/Ajax 更改

ios - 如何在 didSelectRowAtIndexPath 之后运行 prepareForSegue?

ios - UICollectionView 背景图像在旋转时不拉伸(stretch)

ios - 如何根据传入远程通知负载中定义的类别添加不同的操作? swift 更新

ios - LiveSDK for iOS消息将释放实例