【问题标题】:Adding MKannotation to a mapview cause EXC_BAD_ACCESS error将 MKannotation 添加到地图视图会导致 EXC_BAD_ACCESS 错误
【发布时间】:2014-08-13 21:21:53
【问题描述】:

用正确的值更新核心数据后,我想将这些值添加到地图视图中。 这是我为此编写的代码:

-(void)updateMapWithPredicate:(NSPredicate *)predicate
{
    int numberOfElementiOnMap = 0;
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.ActiviIndicator startAnimating];

        [self.mapView removeAnnotations:self.mapView.annotations];
    });
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Photo"];
    if (predicate) {
        request.predicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[[NSPredicate predicateWithFormat:@"(latitude != nil) AND (longitude != nil)"]
                                                                                 ,predicate]];
    } else {
        request.predicate = [NSPredicate predicateWithFormat:@"(latitude != nil) AND (longitude != nil)"];
    }

    //Get all different coordinate from core data.
    [request setPropertiesToFetch:@[@"latitude", @"longitude"]];
    [request setReturnsDistinctResults:YES];
    [request setResultType:NSDictionaryResultType];
    // Execute the fetch
    NSError *error = nil;
    NSArray *photos = [self.context executeFetchRequest:request error:&error];
    for (NSDictionary *coordinateDic in photos) {
        NSPredicate *predicateToSend;
        if (predicate) {
            /* Get all pictures that corresponding to the coordinate inside the coordinateDic
             */
            predicateToSend = [NSCompoundPredicate andPredicateWithSubpredicates:@[[NSPredicate predicateWithFormat:@"(latitude == %@) AND (longitude == %@)",
                                                                                    [coordinateDic valueForKey:@"latitude"], [coordinateDic valueForKey:@"longitude"]],predicate]];
        } else {
            predicateToSend = [NSPredicate predicateWithFormat:@"(latitude == %@) AND (longitude == %@)",[coordinateDic valueForKey:@"latitude"], [coordinateDic valueForKey:@"longitude"]];
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            //get all picture with the same lautide and longitude that are specified on predicate
            NSArray *photos2 = [Photo pictureFromContext:self.context withPredicate:predicateToSend];
            //if the pictures are more then one, we add only one picture, and we write the number of pictures as a subtitle of the mkannotationview
            if ([photos2 count] > 1) {
                Photo *photo = [photos2 lastObject];
                photo.photoDescription = [NSString stringWithFormat:@"album with %lu picures",(unsigned long)[photos2 count]];
                if (photo) {
                  //  [self.mapView addAnnotation:photo];
                }                
            } else { //add the only pictures
                if ([photos2 firstObject]) {
                   [self.mapView addAnnotation:[photos2 firstObject]];
                }
            }
        });
    }
}

在这段代码中,我基本上从核心日期检索需要的值,然后将其添加到地图中。

我添加到地图中的对象显然符合<MKAnnotation> 协议。我在[self.mapView addAnnotation:[photos2 firstObject]];line 上收到错误消息。奇怪的事实是,我从核心日期获得的一些对象被正确添加到地图中。我试图通过启用 NSZombie 来调试代码,但我得到了同样的错误。我还检查了坐标,一切都很好。我在调试代码时发现的唯一区别是: 正确添加到地图的对象在调试器中如下所示:

当我收到错误时,我添加到地图的对象在模拟器上看起来像这样:

当我打印以下内容时:0 我得到这个:

Printing description of *([0]->[0]):
(Photo_Photo_) [0] = {}

它看起来像一个指向空实体的指针。 你知道我该如何解决这个问题吗? 谢谢

【问题讨论】:

  • 当您说“我从核心日期获取的某些对象已正确添加到地图中”时,您是说您在 MapView 上显示了成功的地图注释,并且此错误仅发生一些时间?
  • 是的,正常行为是这样的:打开应用程序 --> 切换到地图视图 --> 从核心数据向地图添加 mkannotation(一切正常)---> 更新核心数据---> 使用新的核心数据值更新地图 --> 崩溃
  • 所以我不能 100% 确定,但问题可能是您试图在未删除注释的情况下将相同的对象(尽管已修改)添加到地图视图。在重新添加之前尝试从地图中删除注释,看看是否有帮助。
  • 在添加注释之前,我使用 [self.mapView removeAnnotations:self.mapView.annotations];移除地图上所有注解的方法(见代码)
  • @Max_Power89 最后实际上是 Map Kit 中的一个错误。用 100 个引脚试试,你会发现它是有效的。我向苹果发布了一个错误报告,我会将一个 repo 上传到 github,其中包含一个重现该错误的项目。

标签: ios objective-c xcode mkmapview mkannotationview


【解决方案1】:

提交错误报告后,Apple 告诉了我问题的解决方案。问题是我以不符合 KVO 的方式更新坐标。我存储像你一样的属性,有纬度和经度。尝试将其添加到您的 Photo 类中。

- (void)willChangeValueForKey:(NSString *)key
{
    if ([key isEqualToString:@"latitude"] || [key isEqualToString:@"longitude"]) { [self willChangeValueForKey:@"coordinate"]; }
    [super willChangeValueForKey:key];
}

- (void)didChangeValueForKey:(NSString *)key
{
    if ([key isEqualToString:@"latitude"] || [key isEqualToString:@"longitude"]) { [self didChangeValueForKey:@"coordinate"]; }
    [super didChangeValueForKey:key];
}

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-19
    • 1970-01-01
    • 1970-01-01
    • 2020-10-02
    • 2010-11-17
    • 1970-01-01
    相关资源
    最近更新 更多