Ios5 AFX2B;NsOperationQueue-下载数千个图像

Ios5 AFX2B;NsOperationQueue-下载数千个图像,ios5,nsoperationqueue,afnetworking,Ios5,Nsoperationqueue,Afnetworking,我正在执行一项任务(仅限iOS5+),该任务涉及从服务器下载数千张图像。图像属于某些类别,每个类别可以有数百个图像。我需要做的是:- 1) 如果应用处于活动状态,请确保该应用在后台下载任何缺失的图像(即使用户正在浏览与照片无关的其他应用区域) 2) 当用户单击照片类别时,该类别中的图像必须作为高优先级下载,因为这些图像需要立即可见 仅当映像尚未脱机可用时,才会发生上述所有情况。下载后,图像将从本地存储中使用 为了解决这个问题,我使用的逻辑是:- 1) 在AppDelegate.m中的applic

我正在执行一项任务(仅限iOS5+),该任务涉及从服务器下载数千张图像。图像属于某些类别,每个类别可以有数百个图像。我需要做的是:-

1) 如果应用处于活动状态,请确保该应用在后台下载任何缺失的图像(即使用户正在浏览与照片无关的其他应用区域)

2) 当用户单击照片类别时,该类别中的图像必须作为高优先级下载,因为这些图像需要立即可见

仅当映像尚未脱机可用时,才会发生上述所有情况。下载后,图像将从本地存储中使用

为了解决这个问题,我使用的逻辑是:-

1) 在AppDelegate.m中的
applicationdidebecomeactive
,我开始下载任何缺失的图像。为此,我进行了一次核心数据查询,找出丢失的图像,并开始在具有后台优先级的线程中下载它们。大概是这样的:-

 dispatch_queue_t imageDownloadQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
dispatch_async(imageDownloadQueue, ^{
    [DataDownloader downloadMissingImages];
});
dispatch_release(imageDownloadQueue);
NSOperationQueue *downloadQueue = [[NSOperationQueue alloc] init];
        downloadQueue.maxConcurrentOperationCount = 20;

        for(MyImage *img in matches)
        {
            NSURLRequest *request = [NSURLRequest requestWithURL:img.photoUrl];
            AFImageRequestOperation *operation = [AFImageRequestOperation imageRequestOperationWithRequest:request success:^(UIImage *image) {

                [MyImage imageFromAPI:image inManagedObjectContext:document.managedObjectContext];

                NSLog(@"Successfully downloaded image for %@", img.title);      
            }];

            [downloadQueue addOperation:operation];
        }
downloadMissingImages
代码如下所示:-

 dispatch_queue_t imageDownloadQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
dispatch_async(imageDownloadQueue, ^{
    [DataDownloader downloadMissingImages];
});
dispatch_release(imageDownloadQueue);
NSOperationQueue *downloadQueue = [[NSOperationQueue alloc] init];
        downloadQueue.maxConcurrentOperationCount = 20;

        for(MyImage *img in matches)
        {
            NSURLRequest *request = [NSURLRequest requestWithURL:img.photoUrl];
            AFImageRequestOperation *operation = [AFImageRequestOperation imageRequestOperationWithRequest:request success:^(UIImage *image) {

                [MyImage imageFromAPI:image inManagedObjectContext:document.managedObjectContext];

                NSLog(@"Successfully downloaded image for %@", img.title);      
            }];

            [downloadQueue addOperation:operation];
        }
这是可行的,但它会阻塞主UI,应用程序会在一段时间后崩溃。这是我尝试下载大约700张图片的时候。如果有更多的图像,它肯定会崩溃

2) 当用户单击某个类别时,我需要首先下载这些图像,因为它们必须立即显示给用户。我不知道如何才能中断missingImages呼叫,并告诉它在其他图像之前开始下载某些图像

因此,基本上,我需要在后台下载所有丢失的图像,但是如果用户正在浏览照片类别,这些图像必须在下载队列中具有高优先级

我不知道如何使它有效地工作。有什么想法吗

崩溃日志如下所示

PAPP(36373,0xb065f000) malloc: *** mmap(size=16777216) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
PAPP(36373,0xb065f000) malloc: *** mmap(size=16777216) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
Jun 24 11:39:45 MacBook-Pro.local PAPP[36373] <Error>: ImageIO: JPEG    Insufficient memory (case 4)
PAPP(36373,0xb065f000)malloc:**mmap(大小=16777216)失败(错误代码=12)
***错误:无法分配区域
***在malloc\u error\u break中设置断点以进行调试
PAPP(36373,0xb065f000)malloc:**mmap(大小=16777216)失败(错误代码=12)
***错误:无法分配区域
***在malloc\u error\u break中设置断点以进行调试
6月24日11:39:45 MacBook-Pro.local PAPP[36373]:图像IO:JPEG内存不足(案例4)

提前感谢。

关于崩溃,我猜您的应用程序会因为以下两种选择之一而被终止:

  • 应用程序变得无响应(因此对iOS sentinel进程没有响应)

  • 循环中使用的内存太多,导致700多个请求操作

  • 为了弄清楚到底发生了什么,您应该提供关于崩溃的更多信息(控制台日志)。在任何情况下,修复方法都是以10或20个图像块的形式加载图像(如果你愿意,你甚至可以一个接一个地加载图像,我看不出有什么问题)

    关于第二点,关于这个:

  • 在主线程中下载更高优先级的映像(当然,通过异步下载来避免阻塞UI)

  • 在开始下载“脱机”映像之前,您需要检查映像是否已通过“更高优先级”下载进行下载

  • 为了更好地处理第2点,您可能需要将自定义操作排队,而不是将
    AFImageRequestOperation
    排队,以便在实际下载之前进行检查

    编辑:

    关于在区块中下载图像,您可以使用调度组对网络操作进行分组:

    dispatch_group_t group = dispatch_group_create();
    
    <your_core_data_query>
    
    for (...) {
        dispatch_group_enter(group);
    
            NSURLRequest *request = [NSURLRequest requestWithURL:img.photoUrl];
            AFImageRequestOperation *operation = [AFImageRequestOperation imageRequestOperationWithRequest:request success:^(UIImage *image) {
                [MyImage imageFromAPI:image inManagedObjectContext:document.managedObjectContext];
                NSLog(@"Successfully downloaded image for %@", img.title);
    
                dispatch_group_leave(group);     //<== NOTICE THIS
            }];
    
    }
    
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    dispatch_release(group);
    
    dispatch\u group\u t group=dispatch\u group\u create();
    对于(…){
    调度组输入(组);
    NSURLRequest*request=[nsurlRequestRequestWithURL:img.photoUrl];
    AFImageRequestOperation*操作=[AFImageRequestOperation imageRequestOperationWithRequest:请求成功:^(UIImage*图像){
    [MyImage imageFromAPI:ImageInManagedObjectContext:document.managedObjectContext];
    NSLog(@“已成功下载%@”的图像),img.title;
    
    派遣组休假(组);//嗨,塞吉奥,你有没有像你建议的那样演示分块下载的代码示例?还有,我如何检查更高优先级的队列是否已经下载了某个图像?有没有相应的代码示例?已经修改了问题以包括崩溃日志-我从每个图像下载中生成缩略图..所以我想700个图像是确定的这是造成内存泄漏的原因..感谢代码..我注意到AFHTTpClient已将BatchOfHttPrequesStoperations排队,这也使用了调度组,所以我可以使用它..这段代码是否会在后台运行而不阻塞UI..目前它似乎阻塞了UI..据我所知,您正在
    dispatch\u async中执行所有这些操作(imageDownloadQueue,
    ,因此UI不应被阻止。。。