【问题标题】:UIImages NSURLs and ThreadsUIImages NSURL 和线程
【发布时间】:2013-05-06 17:17:26
【问题描述】:

我正在尝试构建一个很好的功能来访问网络以获取图像,如果在网络上找到它们,我会将它们存储在我制作的缓存系统中。 如果图像已经存储在缓存中,我会返回它。 该函数称为getImageFromCache,如果图像在缓存中,则返回图像,否则将进入网络并获取。

代码可能如下所示:

UIImageView* backgroundTiles = [[UIImageView alloc] initWithImage[self getImageFromCache:@"http://www.example.com/1.jpg"]];

现在,由于网络流量的延迟很大,我将继续使用线程。所以我希望图像在我从网络上得到结果之前显示一个临时图像。

我想知道的是如何跟踪这么多按顺序访问的图像,这些图像被这个函数 (getImageFromCache) 添加到UIImageViews。

有些东西在那里行不通:

-(UIImage*)getImageFromCache:(NSString*)forURL{

    __block NSError* error = nil;
    __block NSData *imageData;
    __block UIImage* tmpImage;

    if(forURL==nil) return nil;

    if(![self.imagesCache objectForKey:forURL])
    {
        // Setting a temporary image until we start getting results
        tmpImage = [UIImage imageNamed:@"noimage.png"];

        NSURL *imageURL = [NSURL URLWithString:forURL];
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
            imageData = [NSData dataWithContentsOfURL:imageURL options:NSDataReadingUncached error:&error];
            if(imageData)
            {
                NSLog(@"Thread fetching image URL:%@",imageURL);
                dispatch_async(dispatch_get_main_queue(), ^{
                    tmpImage = [UIImage imageWithData:imageData];
                    if(tmpImage)
                    {
                        [imagesCache setObject:tmpImage forKey:forURL];
                    }
                    else
                        // Couldn't build an image of this data, probably bad URL
                        [imagesCache setObject:[UIImage imageNamed:@"imageNotFound.png"] forKey:forURL];
                   });
            }
            else
                // Couldn't build an image of this data, probably bad URL
                [imagesCache setObject:[UIImage imageNamed:@"imageNotFound.png"] forKey:forURL];

        });

    }
    else
        return [imagesCache objectForKey:forURL];

    return tmpImage;
}

【问题讨论】:

  • 真正的问题是什么?
  • 图片从网上回来后不知道如何管理
  • 您的代码显示您将图像放入字典中。那就是管理他们。我再次问,问题是什么?

标签: ios multithreading cocoa-touch uiimageview uiimage


【解决方案1】:

这不是您问题的直接答案,但您是否知道不需要使用 GCD 异步下载内容(在后台线程上)?只需使用 NSURLConnection 及其委托方法。您的所有代码都将在主线程上,但实际的连接和下载将在后台进行。

(事实上,我已经编写了一个类 MyDownloader,它会为您处理所有这些:

http://www.apeth.com/iOSBook/ch37.html#_http_requests

向下滚动到关于 MyDownloader 及其子类 MyImageDownloader 的部分,它正在完全完成您需要在此处完成的事情。此外,请注意该章中的后续代码显示如何在下载完成时使用通知,提示需要这些图像的表视图重新加载包含图像刚刚到达的图像视图的行。)

【讨论】:

    【解决方案2】:

    从头开始构建它很好,但如果你想保存所有工作,替换 SDWebImage 库有一个下降,它支持来自网络的远程图像,并具有所有功能,如临时图像、异步加载、缓存等,你说你需要

    【讨论】:

      【解决方案3】:

      在您的后台线程中,一旦下载完成并将图像保存到缓存中,我建议您使用NSNotificationCenter 发布通知,让您的应用程序的其他部分知道缓存已更新了。

      这假定应用程序中管理图像视图的任何部分都已使用addObserverForName 方法注册了对这些通知的兴趣。当它收到这样的通知时,它可以尝试再次从缓存中检索图像并在适当的情况下更新其图像视图。

      根据图像视图的数量,您可能希望以某种方式在通知中传递图像 url(例如,在 userInfo 字典中),然后基于此决定应该刷新哪些图像视图而不是让它们都焕然一新。

      我应该补充一点,我还建议摆脱内部的dispatch_async 调用。没有必要这样做,尽管您可能需要向缓存对象添加同步,以便可以从主线程和下载线程安全地访问它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-30
        • 1970-01-01
        • 2016-11-24
        • 2023-03-12
        • 2015-12-27
        • 2011-07-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多