Mapview在iOS 6中崩溃 [英] Mapview crashes in iOS 6
问题描述
当我在iOS 6中加载地图视图时遇到问题。但它与以前的操作系统版本一起工作100%。
I'm having a problem when I'm loading map view in iOS 6. But it's working 100% with previous OS versions.
这是代码:
//.h file
MKMapView *galleryListMap; //map view
NSMutableArray *copyOfAllRecords; //array with locations
这是我的.m文件中的代码结构。我已经合成变量并在 dealloc
方法中发布它们。
And here is the code structure in my .m file. I have synthesized variables and released them in dealloc
method.
//this will runs in a background thread and populateMap method will make all the annotations
//[self performSelectorInBackground:@selector(populateMap) withObject:nil];
//here is populateMap method
-(void)populateMap{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
NSArray *existingpoints = galleryListMap.annotations;
//removes alll the existing points
[galleryListMap removeAnnotations:existingpoints];
//assign point to map view
for(int i = 0; i < [copyOfAllRecords count]; i++) {
Gallery *gallery = (Gallery *)[copyOfAllRecords objectAtIndex:i];//array which has the elements
//create location based on the latitude and longtitude
CGFloat latDelta = gallery.latitude;
CGFloat longDelta = gallery.longitude;
CLLocationCoordinate2D newCoord = {latDelta, longDelta};
//adds the notations
AddressAnnotation *addrAnnotation = [[[AddressAnnotation alloc] initWithCoordinate:newCoord]autorelease];
//assing the location the map
[addrAnnotation setId:i];
[addrAnnotation setTitle:gallery.name];
if([gallery.exhibition length]==0 && !gallery.isResturant){
[addrAnnotation setSubtitle:@""];
}else{
[addrAnnotation setSubtitle:gallery.exhibition];
}
**//gives the exception on this line
[galleryListMap addAnnotation:addrAnnotation];**
}
MKCoordinateRegion region;
MKCoordinateSpan span = MKCoordinateSpanMake(0.2, 0.2);
Gallery *lastGalleryItem = [copyOfAllRecords lastObject];
CLLocationCoordinate2D location = {lastGalleryItem.latitude, lastGalleryItem.longitude};
region.span=span;
region.center=location;
[galleryListMap setRegion:region animated:TRUE];
[galleryListMap regionThatFits:region];
galleryListMap.showsUserLocation = YES;
[pool release];
}
- (MKAnnotationView *) mapView:(MKMapView *)mkmapView viewForAnnotation:(AddressAnnotation *) annotation{
static NSString *identifier = @"currentloc";
if([annotation isKindOfClass:[AddressAnnotation class]]){
MKPinAnnotationView *annView = [[[MKPinAnnotationView alloc]initWithAnnotation:addAnnotation reuseIdentifier:identifier]autorelease];
Gallery *galItem = (Gallery *)[copyOfAllRecords objectAtIndex:annotation.annotationId];
CGRect viewFrame;
UIView *myView;
UIImage *tagImage;
//checks whether the resturant or not
if (galItem.isResturant) {
viewFrame = CGRectMake( 0, 0, 41, 45 );
myView = [[UIView alloc] initWithFrame:viewFrame];
tagImage= [UIImage imageNamed:@"map_restaurant"];
}else{
viewFrame = CGRectMake( 0, 0, 41, 45 );
myView = [[UIView alloc] initWithFrame:viewFrame];
tagImage= [UIImage imageNamed:galItem.mapMarker];
}
UIImageView *tagImageView = [[UIImageView alloc] initWithImage:tagImage];
[myView addSubview:tagImageView];
[tagImageView release];
UIGraphicsBeginImageContext(myView.bounds.size);
[myView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[annView setImage:viewImage];
[myView release];
int recordCount =[copyOfAllRecords count];
if (recordCount != 0 ) {
UIButton *annotationButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[annotationButton addTarget:self action:@selector(showLinks:) forControlEvents:UIControlEventTouchUpInside];
annotationButton.tag = [annotation annotationId];
annView.rightCalloutAccessoryView = annotationButton;
}
if([annotation annotationId]==recordCount-1){
//hides loading screen
//[HUD hide:YES];
self.mapAlreadyLoaded = YES;
}
return annView;
}
return nil;
}
我得到的例外是:
*** Terminating app due to uncaught exception 'NSGenericException',
reason: '*** Collection <__NSArrayM: 0x21683870> was mutated while being enumerated.'
*** First throw call stack:
(0x32dc62a3 0x3259897f 0x32dc5d85 0x37c4d33b 0x37c50373 0x86e63 0x37dcc67d 0x36e52311 0x36e521d8)
但如果我使用:
[self populateMap];
//[self performSelectorInBackground:@selector(populateMap) withObject:nil];
申请工作正常。
任何想法为什么会发生这种情况?
Any idea why this is happening?
推荐答案
这可能会发生多种原因 - 错误告诉你在某些情况下指向您(或基础iOS库)尝试枚举在该过程正在进行时更改的数组。
There are a number of reasons this could be happening - the error is telling you that at some point you (or an underlying iOS library) tried to enumerate an array that changed while that process was on-going.
当您<$ c $时它可以工作的事实c> populateMap 关闭主线程,不工作,当你在辅助线程上调用它时表明存在某种竞争条件。
The fact that it works when you populateMap
off the main thread and doesn't work when you call it on a secondary thread suggests there's some sort of race condition going on.
请记住,并非所有 UIKit
都是线程安全的(大部分都不是) - 所以那里可能是那里的一个问题。您仍然在后台线程上向地图添加注释:
Bear in mind that not all of UIKit
is thread safe (most of it isn't) - so there might be an issue there. You add the annotations to your map whilst still on a background thread:
[galleryListMap addAnnotation:addrAnnotation];
...这也是发生崩溃的线。按理说,当您向MapView添加注释时,它可能会迭代其所有当前注释以更新显示。因为你正在通过后台线程进行这些调用,这可能会带来很多问题。
...this is also the line on which your crash happens. It stands to reason that when you add an annotation to a MapView it probably iterates through all its current annotations to update the display. Because you're making these calls off a background thread this could introduce lots of problems.
相反,试试这个:
[galleryListMap performSelectorOnMainThread:@selector(addAnnotation:)
withObject:addrAnnotation
waitUntilDone:YES]
这将强制地图视图在主线程上添加注释。作为一般规则, UIKit
中只有一些是线程安全的(Apple文档有一个完整的列表)。
This will force the map view to add the annotation on the main thread. As a general rule, there are only a few things in UIKit
that are thread-safe (the apple documentation has a complete list).
这篇关于Mapview在iOS 6中崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!