使用NSOperationQueue在后台

问题描述:

下载表格,我需要下载一些,我已经使用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]; 

的想法是从网络service.For形式,它应该得到不影响屏幕操作执行。在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]; 
    } 


} 

请问您能否帮我解决这个问题的正确方法。我知道,这段代码没有正确实现线程化。请在此引导我。非常感谢您的提前。

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

1)初始化你的按钮标签,每个清单指数

2)的指数持下载的检查清单

3)NSMutableIndexSet禁用点击按钮,同时其下载

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]; 

} 
+0

使用类别将模型附加到UIButton的 http://muhammadzahidimran.com/2016/12/09 /添加数据到sdk-classes-using-categories/ – Zahid

+0

@Marat Ibragimov:你能否更详细地解释所有清单的后台下载。我们也可以添加像checklistIDs这样的随机数作为NSMutableIndexSet中的索引吗?非常感谢您的回复。 – iOSManiac

+0

我只添加了按钮点击的部分,我会将背景部分添加到我的答案中。我保存的索引是检查清单是否已下载,按钮的标签属性包含每个检查列表的索引,因为我假设您在下载过程中不更改tempArray。一旦您有来自url的响应会话你和那里没有错误你将索引保存到NSMutableIndexSet(只有其tempArray中的清单的索引) –