使用NSOperationQueue在后台下载表单

时间:2016-12-14 11:11:04

标签: objective-c multithreading nsoperationqueue

我需要从网络服务下载一些表格。因为我使用了NSOperationQueue这样

operationQueue = [NSOperationQueue new];
    for (int i=0;i<[tempArray count];i++) {
        CheckList * checklist = (CheckList *)[tempArray objectAtIndex:i];

        NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
                                                                                selector:@selector(downloadChecklistsInBackground:)
                                                                                  object:checklist];
        [operationQueue addOperation:operation];

这个想法是,它应该在不影响屏幕操作的情况下执行。在UI中,每个表单都有单独的下载按钮。如果用户点击其中任何一个表单,应该立即下载它,并且应该从后台进程中删除。代码如下所示。

-(void)downloadChecklistsInBackground:(CheckList *)checklist
{
    BOOL isDone = NO;
    for (int j=0; j<[selectedArray count]; j++) {
        if([checklist.checklistId isEqualToString:[selectedArray objectAtIndex:j]])
        {
            isDone = YES;

        }
    }
    if(!isDone)
    {
        [backGroundQueueArr addObject:checklist];

        NSString * urlStr = [[BASE_URL stringByAppendingString:DOWNLOAD_CHECKLIST_URL] stringByAppendingFormat:@"%@/%d/%@/%@/%@",[ChecklistSingleton sharedSingleton].userSSO,[checklist.checklistId intValue],checklist.language,checklist.baseFormId,checklist.versionNo];
        NSURL * url = [NSURL URLWithString:urlStr];
        NSLog(@"url is %@",url);

        NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
        NSURLSession *session = [NSURLSession sessionWithConfiguration:config];

        NSMutableURLRequest * request = [[NSMutableURLRequest alloc] initWithURL:url];
        AppDelegate * appDelegateObj = (AppDelegate *)[[UIApplication sharedApplication] delegate];
        [request setValue:[NSString stringWithFormat:@"Bearer %@",appDelegateObj.accessToken ]forHTTPHeaderField:@"Authorization"];
        [request setTimeoutInterval:240.0];
        [request setValue:@"Application/JSON" forHTTPHeaderField:@"Content-Type"];
        NSURLSessionDataTask * downloadTask =[session dataTaskWithRequest:request completionHandler:^(NSData * data, NSURLResponse * response, NSError * error)
                                              {
                                                  NSString * str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
                                                  NSLog(@"response is %@",str);
                                              }];
        [downloadTask resume];

    }


}
-(void)downloadCecklistWithChecklist:(CheckList *)check5
{

    [selectedArray addObject:check5];
    BOOL isDownloaded = NO;
    for (int j=0; j<[backGroundQueueArr count]; j++) {
        CheckList * checklistTobeChecked = [backGroundQueueArr objectAtIndex:j];
        if([checklistTobeChecked.checklistId isEqualToString:check5.checklistId])
        {
            isDownloaded = YES;
        }
    }
    if(!isDownloaded)
    {

    NSString * urlStr = [[BASE_URL stringByAppendingString:DOWNLOAD_CHECKLIST_METADATA_SUBURL] stringByAppendingFormat:@"%@/%d/%@/%@/%@",[ChecklistSingleton sharedSingleton].userSSO,[check5.checklistId intValue],check5.language,check5.baseFormId,check5.versionNo];
    NSURL * url = [NSURL URLWithString:urlStr];
    NSLog(@"url is %@",url);

    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:config];

    NSMutableURLRequest * request = [[NSMutableURLRequest alloc] initWithURL:url];
    AppDelegate * appDelegateObj = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    [request setValue:[NSString stringWithFormat:@"Bearer %@",appDelegateObj.accessToken ]forHTTPHeaderField:@"Authorization"];
    [request setTimeoutInterval:240.0];
    [request setValue:@"Application/JSON" forHTTPHeaderField:@"Content-Type"];
    NSURLSessionDataTask * downloadTask =[session dataTaskWithRequest:request completionHandler:^(NSData * data, NSURLResponse * response, NSError * error)
                                          {
                                              NSString * str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
                                              NSLog(@"response is specific %@",str);
                                          }];
    [downloadTask resume];
    }


}

请你帮我解决这个问题的正确方法。我知道,这段代码没有正确实现线程。请指导我。非常感谢你。

1 个答案:

答案 0 :(得分:0)

NSURLSession已经包装了异步下载操作,在这种情况下,您不必从NSInvocationOperation中调用它。 我建议你:

1)使用每个清单索引的索引

初始化您的按钮标记

2)保存已下载检查清单的NSMutableIndexSet

3)在下载时禁用点击按钮

4)添加下载核对清单的索引

5)检查是否所有列表都已下载如果是,则从tempArray中删除所有列表

6)启用按钮

为所有按钮创建一般事件,例如:

-(IBAction)myButtonClickEvent:(id)sender{

  // 2 - protects your data from being downloaded twice
  if([indexSet contains:sender.tag])
     return;
  // 3 - disable while downloading
  sender.enabled = NO;
  CheckList * check5 = [tempArray objectAtIndex : sender.tag];
  NSString * urlStr = [[BASE_URLstringByAppendingString:DOWNLOAD_CHECKLIST_METADATA_SUBURL] stringByAppendingFormat:@"%@/%d/%@/%@/%@",[ChecklistSingleton sharedSingleton].userSSO,[check5.checklistId intValue],check5.language,check5.baseFormId,check5.versionNo];
  NSURL * url = [NSURL URLWithString:urlStr];
  NSLog(@"url is %@",url);
  NSURLSessionConfiguration *config = [NSURLSessionConfiguration  defaultSessionConfiguration];
  NSURLSession *session = [NSURLSession sessionWithConfiguration:config];

  NSMutableURLRequest * request = [[NSMutableURLRequest alloc] initWithURL:url];
AppDelegate * appDelegateObj = (AppDelegate *)[[UIApplication sharedApplication] delegate];
 [request setValue:[NSString stringWithFormat:@"Bearer %@",appDelegateObj.accessToken ]forHTTPHeaderField:@"Authorization"];
 [request setTimeoutInterval:240.0];
 [request setValue:@"Application/JSON" forHTTPHeaderField:@"Content-Type"];
NSURLSessionDataTask * downloadTask =[session dataTaskWithRequest:request completionHandler:^(NSData * data, NSURLResponse * response, NSError * error)
                                      {
                                          // 4 - add index of downloaded checklist
                                          [indexSet addIndex:sender.tag];
                                          //5 - remove all checklists if all of them are downloaded
                                          if([indexSet count]==[tempArray count])
                                                 [tempArray removeAllObjects];
                                          NSString * str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
                                          NSLog(@"response is specific %@",str);

                                          //6 - enable the button
                                          sender.enabled = YES;

                                      }];
[downloadTask resume];

}