1

我正在使用带有注释的 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. 为 Map 中的每条记录添加注释。注意:我有大约 250 个注释要显示在地图上

此代码在第一次加载时工作并正确显示注释,但是当我切换到另一个 SubView 并返回到此 SubView 时,它会崩溃并显示以下消息。

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

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

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

PS:我对使用 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]];
    }
}
4

2 回答 2

2

您的代码有几个问题。即使它们不应该直接产生僵尸,我也会指出其中的一些:

1

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

您最好使用重用标识符来避免创建多余的 MKAnnotationView。你应该这样做:

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

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

[mapView removeAnnotations:mapView.annotations];

3

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

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

NSArray *site = [_siteList copy];

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

site = _siteList; 

或者曾经使用 _siteList 而不是站点。

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

于 2013-06-02T14:36:49.377 回答
1

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

于 2013-06-02T14:09:44.067 回答