iOS (cs193p) : Issue using a delegate in a MapViewController to get an image using a different thread from another controller

标签 ios xcode cs193p

我正在关注有关 iOS 5.0 开发的优秀 CS193P 讲座:
http://www.stanford.edu/class/cs193p/cgi-bin/drupal/

我现在在任务 #5,要求的任务 #5b。 单击 map 上的注释时,我需要显示带有缩略图的标注。

我成功地使用以下代码(使用 Flickr)做到了这一点。

MapViewController.h:

@class MapViewController;

@protocol MapViewControllerDelegate <NSObject>

- (UIImage *)mapViewController:(MapViewController *)sender imageForAnnotation:(id <MKAnnotation>)annotation;

@end

@interface MapViewController : UIViewController

@property (nonatomic, strong) NSArray *annotations; // of id <MKAnnotation>
@property (nonatomic, weak) id <MapViewControllerDelegate> delegate;

@end

MapViewController.m:

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)annotationView
{
    if ([annotationView.leftCalloutAccessoryView isKindOfClass:[UIImageView class]]) {
        UIImage *image = [self.delegate mapViewController:self imageForAnnotation:annotationView.annotation];
        [(UIImageView *)annotationView.leftCalloutAccessoryView setImage:image];
    }
}

PhotoListTableViewController.m:

@interface PhotoListTableViewController() <MapViewControllerDelegate>

- (UIImage *)mapViewController:(MapViewController *)sender imageForAnnotation:(id <MKAnnotation>)annotation
{
    UIImage *image = nil;
    if ([annotation isKindOfClass:[FlickrAnnotation class]]) { // make sure the annotation is a FlickrAnnotation
        FlickrAnnotation *flickrAnnotation = (FlickrAnnotation *)annotation;
        NSURL *photoUrl = [FlickrFetcher urlForPhoto:flickrAnnotation.photo format:FlickrPhotoFormatSquare];
        image = [UIImage imageWithData:[NSData dataWithContentsOfURL:photoUrl]];
    }
    return image;
}

@end

我在 mapView:didSelectAnnotationView: 方法中使用 MapViewController 的委托(delegate)来从另一个 Controller PhotoListTableViewController 检索图像(以确保我有一个通用的 MapViewController)。

工作正常...但我需要修改此代码以在另一个线程中调用 Flickr。 所以我为此修改了 mapViewController:imageForAnnotation: 方法:

- (UIImage *)mapViewController:(MapViewController *)sender imageForAnnotation:(id <MKAnnotation>)annotation
{
    __block UIImage *image = nil;
    if ([annotation isKindOfClass:[FlickrAnnotation class]]) { // make sure the annotation is a FlickrAnnotation
        FlickrAnnotation *flickrAnnotation = (FlickrAnnotation *)annotation;
        dispatch_queue_t downloadQueue = dispatch_queue_create("ThumbnailDownloader", NULL);
        dispatch_async(downloadQueue, ^{
            NSURL *photoUrl = [FlickrFetcher urlForPhoto:flickrAnnotation.photo format:FlickrPhotoFormatSquare];
            dispatch_async(dispatch_get_main_queue(), ^{ // execute on the main thread
                image = [UIImage imageWithData:[NSData dataWithContentsOfURL:photoUrl]];
            });
        });
        dispatch_release(downloadQueue);
    }
    return image;
}

但是,使用此代码,不显示任何缩略图。我知道这是因为当方法“返回图像”时,图像仍然是 nil 导致 downloadQueue 线程尚未完成。我试图像这样在 block 内“返回图像”:

return [UIImage imageWithData:[NSData dataWithContentsOfURL:photoUrl]];

但是编译器不喜欢那样:

Incompatible block pointer types passing 'UIImage *(^)(void)' to parameter of type 'disptach_block_t' (aka 'void (^)(void)')

我知道 block 开头的 ^{ 表示无效,但是可以更改为返回 UIImage 吗?还是我一开始就做错了?

我只是不知道如何将图像从 PhotoListTableViewController 返回到 MapViewController。应该怎么做?

最佳答案

我正在做同样的作业。我在调用 tableview controller 委托(delegate)时切换线程,而不是等到 tableview controller 获取图像,这对我有用。

在代码中:

-(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view { //NSLog(@"Annotation selected, getting thumbnail");

dispatch_queue_t downloadQueue = dispatch_queue_create("flickr download", NULL);
dispatch_async(downloadQueue, ^{
    UIImage *image = [self.delegate thumbNailImageForAnnotation:view.annotation sender: self];

    dispatch_async(dispatch_get_main_queue(), ^{

        [(UIImageView *)view.leftCalloutAccessoryView setImage:image];

    });

});

关于iOS (cs193p) : Issue using a delegate in a MapViewController to get an image using a different thread from another controller,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14531299/

相关文章:

ios - 从 SCNScene 到 SKScene 的转换 : Swift

ios - 音频播放有问题

ios - PayU支付网关支付成功后如何得到响应?

xcode - 将自定义对象添加到对象库

swift - 在 SwiftUI 中强制 View 位于 View 的右下角

iphone - iPhone开发中有没有快捷方式进入/Resources/文件夹?

iphone - NSNotification ...正确的方法?

ios - 打开新的 View Controller

ios - 游戏中心不保存分数

ios - 在核心数据中使用 UIManagedDocument 的标准(或正确)方法是什么