3

使用AFNetworking,我需要在後臺下載〜100張圖像並將它們存儲到磁盤,同時確保我的應用中的任何其他網絡連接優先。AFNetworking:中斷較高優先級請求的後臺請求

~~~~~~~

我已經得到了有4個標籤的應用程序。每個選項卡基本上都做同樣的事情:從服務器拉下JSON響應,並顯示圖像的縮略圖網格,按需拉下每個圖像(使用AF的ImageView類別)。點擊縮略圖會將您帶到詳細視圖控制器,您可以看到更大的圖像。每個選項卡的響應和圖像都不相同。

有一個新要求提前提取第4個標籤的所有圖像,理論上在用戶點擊第4個標籤時,JSON數據和圖像正在從磁盤讀取。

我現在已經或多或少地做了這個工作,第4個標籤預取並保存到後臺線程上執行的磁盤,所以主線程不鎖定。但是,當用戶處於第1,第2或第3個選項卡時,網絡請求將被預取網絡請求阻止。

我使用AFNetworking,這裏是我使用的時候標籤1,2或3個加載代碼:

// this network request ends up getting blocked by the network request that 
// is fired upon the application becoming active 
- (void)getAllObjectDataWithBlock:(AFCompletionBlockWrapper)block 
{ 
    [[[MyAPIClient] sharedClient] getPath:@"" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) { 
     block(operation, responseObject, nil); 
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
     block(operation, nil, error); 
    }]; 
} 

這裏是當我的應用程序成爲啓動我正在使用的代碼,因此任何網絡請求從主線程拉開序幕

// this network request runs in the background, but still blocks requests 
// that should have a higher priority 
- (void)applicationDidBecomeActive:(UIApplication *)application 
{ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ 
     NSOperationQueue *imageQueue = [[NSOperationQueue alloc] init]; 
     [imageQueue setMaxConcurrentOperationCount:8]; 

     for (NSString *imageURL in self.images) {      
      NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL imageURL]]; 

      AFImageRequestOperation *operation = [[AFImageRequestOperation alloc] initWithRequest:request]; 
      [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { 
       NSLog(@"success"); 
      } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
       NSLog(@"fail"); 
      }]; 

      [imageQueue addOperation:smallOperation]; 
     } 
    }); 
} 

我怎樣組織的事情中斷那些被後臺線程拉開序幕:預取第四屆標籤內容?

回答

3

我不知道你可以很容易地中斷正在運行的操作,除非你想給它們發一個cancel - 但你必須看看AFImageRequestOperation是否注意到isCancelled

您是否嘗試過使用setQueuePriority?您可以以低優先級啓動所有預提取請求,然後添加具有更高優先級的當前選項卡請求。我相信運行操作會完成,但一旦完成,您的高優先級操作將在排隊的低優先級操作之前進行排定。

+3

如果所有操作都在同一個操作隊列中,那麼'setQueuePriority'工作,如果他使用的是'UIImageView'類別,則不適用。所以解決方法是或者將該類別與其他請求使用相同的類別,或者使用可在隊列上下文中工作的setThreadPriority。 – mattt

+1

我最終使用的解決方案是對AFNetworking的UIImageView類進行猴子修補,以暴露af_sharedImageRequestOperationQueue,以便公開訪問,並設置我需要在後臺運行的所有特定操作的queuePriority(NSOperationQueuePriorityVeryLow)和threadPriority(0.25)。不幸的是,只要設置queuePriority,我的應用程序就無法響應,直到所有後臺處理完成,所以我必須全部完成這三個操作。 – djibouti33