将块作为参数的函数并不总是返回

时间:2012-10-26 13:42:03

标签: iphone ios objective-c-blocks

我写了一个从网上下载图片的功能。它需要块作为参数。一切正常,直到我添加了一些内存缓存。如果图像在缓存中是alredy,则函数不会返回(但是块不是nil)。

- (void) downloadImageFromURL:(NSURL *) url completionBlock:(void (^)(UIImage *image, NSError *error)) block {

dataHandler = [DataHandler sharedInstance];

UIImage *img=[dataHandler.avatarImages objectForKey:[url absoluteString]];
//image is in cache
if (img) {
    block(img, nil);
}
//not in cache, download it (works ok)
else {

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul), ^{
        NSData *imageData = [NSData dataWithContentsOfURL:url];
        UIImage *picture=[UIImage imageWithData:imageData];
        if(picture) {
            //save to cache
            [dataHandler.avatarImages setObject:picture forKey:[url absoluteString]];
            block(picture, nil);
        }
        else {
            NSError *error = [NSError errorWithDomain:@"image_download_error" code:1
                                             userInfo:[NSDictionary dictionaryWithObject:@"Can't fetch data" forKey:NSLocalizedDescriptionKey]];
            block(nil, error);
        }

    });
}

这个块被调用如下:

        ImageDownloader *idl=[[ImageDownloader alloc] init];

        NSURL *imageUrl=[NSURL URLWithString:ta.avatarUrl];
        [idl downloadImageFromURL:imageUrl completionBlock:^(UIImage *image, NSError *error)
         {
             if(!error) {
                 dispatch_async(dispatch_get_main_queue(), ^(void) {
                     logo.image=image;
                 });
             } else {
                 NSLog(@"error %@", error);
             }

         }];

1 个答案:

答案 0 :(得分:0)

当缓存中的图像看起来像这样时,将您的调用更改为块:

if (img) {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        block(img, nil);
    });
}

用户不应该关心缓存中的图像是否存在,并且在任何情况下都应该将您的块调用为异步。