0

我有一个从 Flicker 下载图像的应用程序(Xcode 4.5)。我有一个地图视图,它为每张照片的位置放置一个图钉。单击图钉会显示一个注释,其中显示照片的名称及其图像的缩略图。一切正常,直到我决定从主线程下载缩略图(我第一次尝试多线程)。使用我目前拥有的代码,注释不再显示缩略图。

我设置了 4 种方法来执行此任务。第四种方法甚至没有被调用。我希望有人可以查看此代码并指出明显的错误和/或尝试此操作的不同方式:

在我的地图视图控制器类中:

//an annotation was selected
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)aView
{
self.currentAnnotationView = [[MKAnnotationView alloc]init];
self.currentAnnotationView = aView;
[self.delegate mapViewController:self 
    imageForAnnotation:self.currentAnnotationView.annotation];
}

使用委托,上述方法在我的 tableview 控制器类中调用以下内容:

// downloads Flickr image
- (void )mapViewController:(MapViewController *)sender imageForAnnotation:    
      (id<MKAnnotation>)annotation
{      
FlickrPhotoAnnotation *fpa = (FlickrPhotoAnnotation *)annotation;

dispatch_queue_t downloadQueue = dispatch_queue_create("flickr annotation image  
       downloader", NULL);
dispatch_async(downloadQueue, ^{
    NSURL *url = [FlickrFetcher urlForPhoto:fpa.photo format:FlickrPhotoFormatSquare]; 
    NSData *data = [NSData dataWithContentsOfURL:url];
    self.thumbnailImage = [UIImage imageWithData:data];
        dispatch_async(dispatch_get_main_queue(), ^ {
            MapViewController *mvc = [[MapViewController alloc]init];
            [mvc setAnnotationImage];  
        });
    });
}

上述方法通过 mapview 控制器类的实例调用以下消息:

//gets thumbnail image and sets it to the annotation view
 - (void)setAnnotationImage
 {
 UIImage *image = [self.delegate getThumbnailImage];
 [(UIImageView *)self.currentAnnotationView.leftCalloutAccessoryView setImage:image];
 }    

最后,上面的方法使用委托调用表视图控制器类中的以下方法(没有被调用 - 不知道为什么):

//returns the thumbnail image acquired in download
 - (UIImage *)getThumbnailImage;
 {
    return self.thumbnailImage;
 }  
4

1 回答 1

1

该方法没有被调用,因为您没有设置第二个 mapViewController 的委托:

dispatch_async(dispatch_get_main_queue(), ^ {
            MapViewController *mvc = [[MapViewController alloc]init];
            [mvc setAnnotationImage];  
            [mvc setDelegate:self];
        });

应该:

dispatch_async(dispatch_get_main_queue(), ^ {
            MapViewController *mvc = [[MapViewController alloc]init];
            [mvc setDelegate:self];
            [mvc setAnnotationImage];  
        });

...但是您不应该制作新的 mapViewController,您应该在现有的mapViewController(发送方)上设置注释图像。

dispatch_async(dispatch_get_main_queue(), ^ {
            [sender setAnnotationImage];  
        });

...并且在您调用 setAnnotationImage 时,您不妨传入 UIImage(因为您在传递消息时拥有该信息),从而避免了对最后一个委托回调的需要:

更改 setAnnotationImage 方法以接收图像:

- (void)setAnnotationImage:(UIImage*)image
 {
 [self.currentAnnotationView.leftCalloutAccessoryView setImage:image];
 }  

然后你可以一次设置它:

dispatch_async(dispatch_get_main_queue(), ^ {
            [sender setAnnotationImage:self.thumbnailImage];  
        });

...如果这是您唯一需要获取它的地方,那么 self.thumbnailImage 可能不需要是 iVar...

于 2012-12-19T22:17:45.677 回答