2013-04-06 3 views
0

Как вы загружаете изображения в соответствии с AFNetworking? А «по порядку» я также подразумеваю выполнение блоков success по порядку.Загрузка изображений в формате AFNetworking

Первоначально я думал, что будет достаточно использовать NSOperationQueue и установить каждый AFImageRequestOperation в качестве зависимости от следующего. Как это:

- (void) downloadImages 
{ 
    { // Reset 
     [_downloadQueue cancelAllOperations]; 
     _downloadQueue = [[NSOperationQueue alloc] init]; 
     _images = [NSMutableArray array]; 
    } 
    AFImageRequestOperation *previousOperation = nil; 
    for (NSInteger i = 0; i < _imageURLs.count; i++) { 
     NSURL *URL = [_imageURLs objectAtIndex:i]; 
     NSURLRequest *request = [NSURLRequest requestWithURL:URL]; 
     AFImageRequestOperation *operation = [AFImageRequestOperation 
               imageRequestOperationWithRequest:request 
               imageProcessingBlock:nil 
     success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) { 
      [_images addObject:image]; 
      NSLog(@"%d", i); 
     } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {}]; 

     if (previousOperation) { 
      [operation addDependency:previousOperation]; 
     } 
     previousOperation = operation; 

     [_downloadQueue addOperation:operation]; 
    } 
} 

Это печатает i, чтобы при загрузке изображений. Однако, когда запросы уже кэшированы, блоки успеха обрабатываются не в порядке. Я подозреваю, что это ограничение NSOperation, а не AFNetworking.

Я что-то упустил?

ответ

0

Как обходной путь, я храню изображения в словаре и обрабатываю их в порядке, когда запрос выполняется успешно. Как это:

- (void) downloadImages 
{ 
    { // Reset 
     [_downloadQueue cancelAllOperations]; 
     _downloadQueue = [[NSOperationQueue alloc] init]; 
     _images = [NSMutableArray array]; 
     _imageDictionary = [NSMutableDictionary dictionary]; 
    } 
    AFImageRequestOperation *previousOperation = nil; 
    for (NSInteger i = 0; i < _imageURLs.count; i++) { 
     NSURL *URL = [_imageURLs objectAtIndex:i]; 
     NSURLRequest *request = [NSURLRequest requestWithURL:URL]; 
     AFImageRequestOperation *operation = [AFImageRequestOperation 
               imageRequestOperationWithRequest:request 
               imageProcessingBlock:nil 
     success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) { 
      [_imageDictionary setObject:image forKey:@(i)]; 
      [self processImages]; 
     } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {}]; 

     if (previousOperation) { 
      [operation addDependency:previousOperation]; 
     } 
     previousOperation = operation; 

     [_downloadQueue addOperation:operation]; 
    } 
} 

- (void) processImages 
{ 
    for (NSInteger i = _images.count; i < _imageURLs.count; i++) { 
     UIImage *image = [_imageDictionary objectForKey:@(i)]; 
     if (!image) break; 
     [_images addObject:image]; 
     NSLog(@"%d", i); 
    } 
} 

Это всегда печатает i в порядке.

0

Ваше решение будет работать нормально, вот еще один способ сделать это:

Для «идеального» UX вы должны оформить все операции параллельно и обрабатывать изображения по порядку, как они приходят (не ждать, если вы не не нужно).
(обработка ошибок выполняется по-разному здесь)
Вы могли бы попробовать это (непроверенные, и вы можете лучше спроектировать модель [не только использовать массивы, как это]):

- (void) processImage:(UIImage*)image 
{ 
    //do something with the image or just [_images addObject:image] 
} 

- (void) downloadImages 
{ 
    { // Reset 
     [_downloadQueue cancelAllOperations]; 
     _downloadQueue = [[NSOperationQueue alloc] init]; 
    } 

    __block NSMutableArray* queue = [[NSMutableArray alloc] initWithCapacity:[_imageURLs count]]; 

    for (NSURL* url in _imageURLs) { 
     __block NSLock* lock = [[NSLock alloc] init]; 
     __block NSMutableArray* container = [NSMutableArray new]; 
     [lock lock]; 
     [queue addObject:@[lock,container,url]]; 
     NSURLRequest *request = [NSURLRequest requestWithURL:url]; 
     void(^compBlock)(NSURLRequest *request, 
         NSHTTPURLResponse *response, 
         UIImage *image) = ^(NSURLRequest *request, 
              NSHTTPURLResponse *response, 
              UIImage *image) 
     { 
      [container addObject:image]; 
      [lock unlock]; 
     }; 
     NSOperation *operation = [AFImageRequestOperation imageRequestOperationWithRequest:request 
                     imageProcessingBlock:nil 
                        success:compBlock 
                        failure:compBlock]; 
     [_downloadQueue addOperation:operation]; 
    } 

    __block __weak id weakSelf = self; 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     for (NSArray* arr in queue) { 
      NSLock* lock = arr[0]; 
      [lock lock]; 
      NSMutableArray* container = arr[1]; 
      if ([container count]) { 
       [weakSelf processImage:container[0]]; //might want to call this on main thread 
      } else { 
       //error on url = arr[2] 
      } 
      [lock unlock]; 
     } 
    });  
} 
Смежные вопросы