How do I use NSOperationQueue with NSURLSession?

前端 未结 7 963
别跟我提以往
别跟我提以往 2020-12-04 06:48

I\'m trying to build a bulk image downloader, where images can be added to a queue on the fly to be downloaded, and I can find out the progress and when they\'re done downlo

7条回答
  •  再見小時候
    2020-12-04 06:57

    Update: The executing and finishing properties hold the knowledge about the status of the current NSOperation. Once you finishing is set to YES and executing to NO, your operation is considered as finished. The correct way of dealing with it does not require a dispatch_group and can simply be written as an asynchronous NSOperation:

      - (BOOL) isAsynchronous {
         return YES;
      }
    
      - (void) main
        {
           // We are starting everything
           self.executing = YES;
           self.finished = NO;
    
           NSURLSession * session = [NSURLSession sharedInstance];
    
           NSURL *url = [NSURL URLWithString:@"http://someurl"];
    
           NSURLSessionDataTask * dataTask = [session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
    
              /* Do your stuff here */
    
             NSLog("Will show in second");
    
             self.executing = NO;
             self.finished = YES;
           }];
    
           [dataTask resume]
       }
    

    The term asynchronous is quite misleading and does not refers to the differentiation between UI (main) thread and background thread.

    If isAsynchronous is set to YES, it means that some part of the code is executed asynchronously regarding the main method. Said differently: an asynchronous call is made inside the main method and the method will finish after the main method finishes.

    I have some slides about how to handle concurrency on apple os: https://speakerdeck.com/yageek/concurrency-on-darwin.

    Old answer: You could try the dispatch_group_t. You can think them as retain counter for GCD.

    Imagine the code below in the main method of your NSOperation subclass :

    - (void) main
    {
    
       self.executing = YES;
       self.finished = NO;
    
       // Create a group -> value = 0
       dispatch_group_t group = dispatch_group_create();
    
       NSURLSession * session = [NSURLSession sharedInstance];
    
       NSURL *url = [NSURL URLWithString:@"http://someurl"];
    
        // Enter the group manually -> Value = Value + 1
       dispatch_group_enter(group); ¨
    
       NSURLSessionDataTask * dataTask = [session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
    
    
          /* Do your stuff here */
    
          NSLog("Will show in first");
    
          //Leave the group manually -> Value = Value - 1
          dispatch_group_leave(group);
       }];
    
       [dataTask resume];
    
      // Wait for the group's value to equals 0
      dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    
      NSLog("Will show in second");
    
      self.executing = NO;
      self.finished = YES;
    }
    

提交回复
热议问题