MKMapView 与 iOS 8 崩溃
Posted
技术标签:
【中文标题】MKMapView 与 iOS 8 崩溃【英文标题】:MKMapView with iOS 8 crash 【发布时间】:2015-05-22 08:16:09 【问题描述】:我有一个简单的视图控制器,里面有一个 MKMapView 对象,以这种方式定义:
类声明:
@interface GeoViewController : UIViewController <MKMapViewDelegate>
@property (nonatomic, strong) MKMapView* viewMap;
@end
实施:
@implementation GeoViewController
- viewDidAppear:(BOOL)animated
[super viewDidAppear:animated];
viewMap = [[MKMapView alloc] init];
MKCoordinateRegion worldRegion = MKCoordinateRegionForMapRect(MKMapRectWorld);
[viewMap setRegion:worldRegion animated:YES];
viewMap.pitchEnabled = YES;
viewMap.showsUserLocation = YES;
viewMap.delegate = self;
[self.view addSubview:viewMap];
- (void)viewWillDisappear:(BOOL)animated
[super viewWillDisappear:animated];
viewMap.showsUserLocation = NO;
self.viewMap.delegate = nil;
[self.viewMap removeFromSuperview];
- (void)resizeForOrientation:(BOOL)isLandscape withFrame:(CGRect)frame
[super resizeForOrientation:isLandscape withFrame:frame];
const CGRect fullFrame = CGRectMake(0, 0, frame.size.width, frame.size.height);
viewMap.frame = fullFrame;
@end
我第一次展示视图控制器的工作原理。然后我在我的应用程序中导航,如果我回到 GeoViewController,就会崩溃:
控制台上没有消息错误 main.m 已打开并报告“线程 1:EXC_BAD_ACCESS”在调试导航器(左)我收到关于线程 1 的错误报告:
EAGLContext_renderbufferStorageFromDrawable(EAGLContext*, objc_selector*, unsigned int, id)
现在,谷歌搜索了很多,我找不到适合我的解决方案:
我也尝试过 viewDidDisappear,但没办法
[EAGLContext setCurrentContext:nil];
这一行似乎崩溃了:
viewMap.frame = fullFrame;
任何建议将不胜感激!
更新
我在测试中有时会收到其他错误:
检测到opengl线程冲突
【问题讨论】:
可能不相关,但由于viewMap
是一个属性,您应该使用self.viewMap = ...
分配它,而不仅仅是viewMap = ...
。所以viewMap = [[MKMapView alloc] init];
应该是self.viewMap = [[MKMapView alloc] init];
。
【参考方案1】:
我在
中遇到 EXC_ARM_DA_ALIGN 错误EAGLContext_renderbufferStorageFromDrawable(EAGLContext*, objc_selector*, unsigned int, id)
同样,在使用 MKMapView 时。
此问题中提到的解决方法:Adding google maps as subview crashes ios app with exc_bad 为我工作。
在我的目标方案中禁用“GPU 帧捕获”功能起到了作用。
【讨论】:
【参考方案2】:产品 -> 编辑方案 -> 运行 -> 选项 -> 将 GPU 帧捕获设置为禁用。
Refetence Link
【讨论】:
【参考方案3】:我认为是这条线导致了问题
[self.viewMap removeFromSuperview];
因为如果你说你刚刚导航回视图,viewDidLoad 就不会被再次调用。这就是为什么它说“线程 1:EXC_BAD_ACCESS”,因为您访问的是已发布的对象。它在 viewMap.frame = frame 上崩溃,因为您正在访问已释放的 viewMap 对象,因为您将其从其 superView 中删除。
【讨论】:
尝试 viewWillAppear:(BOOL)动画 或者您可以避免从其 superView 中删除 self.viewMap。由于你使用的是ARC,self.viewMap在不用的时候会自动释放。 我已经尝试过在 viewWillAppear 上移动和删除 viewWillDisappear 中的所有代码...在公海上航行! 你能给我这个项目的链接吗?我会尝试构建它。【参考方案4】:viewDidAppear
在您按下控制器时调用,并且当它有另一个控制器按下时调用。因此,在您导航时,您正在删除地图。这同样适用于viewWillDisappear
,因为它将在您将新控制器推到顶部以及最终弹出控制器时调用。
只需更改您的函数以在控制器首次出现时添加地图,并且仅在控制器从导航控制器中弹出时才执行删除。比如:
- viewDidAppear:(BOOL)animated
[super viewDidAppear:animated];
if (self.isMovingToParentViewController)
viewMap = [[MKMapView alloc] init];
MKCoordinateRegion worldRegion = MKCoordinateRegionForMapRect(MKMapRectWorld);
[viewMap setRegion:worldRegion animated:YES];
viewMap.pitchEnabled = YES;
viewMap.showsUserLocation = YES;
viewMap.delegate = self;
[self.view addSubview:viewMap];
- (void)viewWillDisappear:(BOOL)animated
[super viewWillDisappear:animated];
// If being popped off, remove the map view. Otherwise
// leave it alone as we need it when the user navigates
// back
if (self.isMovingFromParentViewController)
viewMap.showsUserLocation = NO;
self.viewMap.delegate = nil;
[self.viewMap removeFromSuperview];
这可确保地图在控制器的生命周期内存在,这应确保对其的任何访问始终有效。
【讨论】:
@Velthune 我注意到您编辑了您的问题并将地图创建移动到viewDidAppear
。您还应该在其周围放置一个防护装置,以便仅在首次按下控制器时创建。请参阅更新的答案。如果您一直添加/删除,则有一段时间您可能没有地图。因此,在第一次显示时创建它并在弹出时将其删除,如更新的答案所示。以上是关于MKMapView 与 iOS 8 崩溃的主要内容,如果未能解决你的问题,请参考以下文章
sigsegv segv_accerr 在 ios7 中崩溃 mkmapview