2013-04-06 45 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]; 
     } 
    });  
}