MKMapView在重新加载时崩溃

时间:2013-06-02 13:51:40

标签: ios objective-c mkmapview

我正在使用带注释的MKMapView。

这是我的代码。

-(void) addAnnotationForCountry {
    [self reloadSiteList];
    [_compoundDetail.sidebar setUserInteractionEnabled:NO];
    [_compoundDetail.detailWindow setUserInteractionEnabled:NO];
    if (_diseaseTable.userInteractionEnabled) {
    [_diseaseTable setUserInteractionEnabled:NO];
    _sitecount = 0;
    _radius = 0;
    NSMutableArray *site = [[NSMutableArray alloc]init];
    site = [_siteList copy];
    for (Site *s in site) {
        if ([s.country isEqualToString:selectedCountry.country] && _sitecount < 20) {
            MKPointAnnotation *annot = [[MKPointAnnotation alloc] init];
            annot.title = [s city];
            annot.coordinate = CLLocationCoordinate2DMake(s.lat, s.log);
            [_mapView addAnnotation:annot];
            _sitecount++;
        }
    }
    if (!_sitecount) {
        [self showNoSiteAvailbleView];
        _radius = 500;
    }
    if (_sitecount && _radius < 100) {
        _radius = 100;
    }
    MKCoordinateSpan span;
    span.latitudeDelta = 100;
    span.longitudeDelta = 100;
    MKCoordinateRegion region;
    region.span = span;
    region.center = CLLocationCoordinate2DMake(selectedCountry.lat, selectedCountry.log);
        [_mapView setRegion:region animated:YES];
    }
}

这就是正在做的事情。

  1. 用户从列表中选择国家/地区。
  2. 从数据库中读取特定国家/地区的坐标。
  3. 根据所选的国家/地区坐标,从数据库中获取记录(站点坐标)。
  4. 为地图中的每条记录添加注释。 注意:我在地图上显示大约250个注释
  5. 此代码在首次加载时正常工作并显示注释,但是当我切换到另一个SubView并返回到此SubView时,它会崩溃并显示以下消息。

    Terminating app due to uncaught exception of class '_NSZombie_NSException'
    libc++abi.dylib: terminate called throwing an exception
    

    当我尝试更改值以仅显示20个注释时,它会起作用并且不会发生崩溃。

    可能是什么问题?这很长时间以来一直困扰着我。

    P.S:我不知道使用Instruments进行内存管理。我试过但直到现在都没有任何结果。

    非常感谢任何类型的帮助。

    由于

    更新

    -(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
        MKAnnotationView *mapAnnotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:nil];
        if ([annotation isKindOfClass:[MKUserLocation class]]) {
            return nil;
        }
        mapAnnotationView.image = [UIImage imageNamed:@"map_icon.png"];
        return mapAnnotationView;
    }
    
    -(void)reloadSiteList {
        _siteList = [[NSMutableArray alloc]init];
        _trialRefList = [[NSMutableArray alloc] init];
        _trialRefList = [[PipelineDatabase initializeDatabase] getTrialReflistForDisease:_selectedDisease];
        for (NSString *ref in _trialRefList) {
            [_siteList addObjectsFromArray:[[PipelineDatabase initializeDatabase] getSitesByRef:ref]];
        }
    }
    

2 个答案:

答案 0 :(得分:2)

您的代码存在一些问题。虽然他们不应该直接制作僵尸,但我会指出其中一些:

1

MKAnnotationView *mapAnnotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:nil];

您最好使用reuseIdentifier来避免创建多余的MKAnnotationView。你应该做这样的事情:

static NSString *ident = @"siteAnnotation";
MKAnnotationView *mapAnnotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:ident];
if (mapAnnotationView == nil)
     mapAnnotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:ident];

2您只需向地图添加注释,但使用removeAnnotations:方法删除它们似乎是合乎逻辑的:

[mapView removeAnnotations:mapView.annotations];

3

NSMutableArray *site = [[NSMutableArray alloc]init];
site = [_siteList copy];

这是一种错误的方式。您初始化一个新对象并立即用另一个对象覆盖它。正确的方法是:

NSArray *site = [_siteList copy];

但即使这样也没有必要,因为我看到你的代码没有使用异步设置_siteList,所以你可以使用

site = _siteList; 

或者使用_siteList而不是site。

4我希望你在其他情况下使用ARC还有很多其他与内存相关的问题

答案 1 :(得分:1)

你有一个僵尸,你的对象被重新计数到0,然后你试图访问它而不实例化它。
尝试将MKMapView对象放在父控制器的属性中,因此切换子视图不会影响生命周期。