【问题标题】:How to wait for finish dataTaskWithRequest?如何等待完成 dataTaskWithRequest?
【发布时间】:2015-10-15 12:15:20
【问题描述】:

如何等待dataTaskWithRequest 的完成?网络抓取完全结束后,我需要执行一些任务。

【问题讨论】:

    标签: ios asynchronous nsurlsession


    【解决方案1】:

    如果确实需要同步请求,可以使用信号量

    我在NSURLSession 上实现了一个小类别来提供此功能。

    .h 文件中:

    @import Foundation.NSURLSession;
    
    @interface NSURLSession (Additions)
    
    + (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error;
    
    @end
    

    .m 文件中:

    @implementation NSURLSession (Additions)
    
    + (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse *__autoreleasing *)responsePointer error:(NSError *__autoreleasing *)errorPointer
    {
        dispatch_semaphore_t semaphore;
        __block NSData *result = nil;
    
        semaphore = dispatch_semaphore_create(0);
    
        void (^completionHandler)(NSData * __nullable data, NSURLResponse * __nullable response, NSError * __nullable error);
        completionHandler = ^(NSData * __nullable data, NSURLResponse * __nullable response, NSError * __nullable error)
        {
            if ( errorPointer != NULL )
            {
                *errorPointer = error;
            }
    
            if ( responsePointer != NULL )
            {
                *responsePointer = response;
            }
    
            if ( error == nil )
            {
                result = data;
            }
    
            dispatch_semaphore_signal(semaphore);
        };
    
        [[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:completionHandler] resume];
    
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    
        return result;
    }
    
    @end
    

    【讨论】:

    • 可悲的是,这在 *errorPointer = error; 上崩溃了。我不能使用它。
    • @AlexZavatone 你能说明你是如何调用这个方法的吗?究竟如何声明错误指针
    【解决方案2】:

    我认为,该方法在类中很明显

    NSURLSessionDataTask *task = [defaultSession dataTaskWithRequest:request
                                                   completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error)
    {
        // code after completion of task
    }];
    [task resume];
    

    【讨论】:

      【解决方案3】:
      - (void) loginRequest:(NSString*) username withPassword:(NSString *) password callback:(void (^)(NSError *error, BOOL success))callback
      {
          NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:request 
                                                           completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
              if (error) {
                  // Handle error, optionally using
                  callback(error, NO);
              }
              else {
                  callback(nil, YES);
              }
          }];
      
          [dataTask resume];
      }
      

      像这样调用这个方法:

      [self loginRequest:@"myUsername" password:@"password" callback:^(NSError *error, BOOL success) {
          if (success) {
              NSLog(@"My response back from the server after an unknown amount of time");
          }
          else {
              NSLog(@"%@", error);
          }
      }];
      

      【讨论】:

        【解决方案4】:

        让我们在 dataTaskWithRequest 的完成块中完成您的任务。 直到您可以显示活动指示器以阻止用户触摸屏幕上的任何内容。

        例子:

        activityIndicator.startAnimating()
        
        let task : NSURLSessionDataTask = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
           activityIndicator.stopAnimating()
          // do your stuff here
        
        });
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-04-03
          相关资源
          最近更新 更多