【问题标题】:How to get return value from NSURLSessionDataTask and call block?如何从 NSURLSessionDataTask 获取返回值并调用块?
【发布时间】:2017-02-22 06:48:28
【问题描述】:

我有一个方法,该方法返回了 nsdata 值,但我不知道如何从 NSURLSessionDataTask 块中获取返回值。以及如何调用 getDownloadFileData 方法。任务代码是:-

来电者:

 NSData *getFileDataResult = [self getDownloadFileData:pathString];

方法:

 - (NSData*) getDownloadFileData : (NSString*) filePath {

  NSURLSessionDataTask *downloadFile = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:filePath] completionHandler:^(NSData *fileData, NSURLResponse *response, NSError *error){
// .....
//  fileData should return out.

  [downloadFile resume];
  });
  // I want to return the fileData after download completion.
  // how to return?
 }

有人可以帮帮我吗?

非常感谢。

【问题讨论】:

标签: ios objective-c block


【解决方案1】:

请查看我的回答,希望对您有所帮助

- (NSData *)getDownloadFileData:(NSString *)filePath {
    __block NSData *responseData = nil;

    dispatch_semaphore_t sema = dispatch_semaphore_create(0);
    NSURLSessionDataTask *downloadFile = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:filePath] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        responseData = data;
        dispatch_semaphore_signal(sema);
    }];
    [downloadFile resume];

    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);

    return responseData;
}

- (void)whereToCall {
    // Because to prevent the semaphore blocks main thread
    dispatch_queue_t myQueue = dispatch_queue_create("com.abc", 0);
    dispatch_async(myQueue, ^{
        NSData *data = [self getDownloadFileData:@"urlString"];
    });
}

- (void)betterGetDownloadFileData:(NSString *)filePath completion:(void (^)(NSData * __nullable data))completion {
    NSURLSessionDataTask *downloadFile = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:filePath] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (completion) {
            completion(data);
        }
    }];
    [downloadFile resume];
}

我建议你应该按照我的建议来设计你的代码,而不是使用块。

【讨论】:

    【解决方案2】:

    首先你把 resume 方法放在了错误的地方。应该是这样的:

     - (NSData*) getDownloadFileData : (NSString*) filePath {
        NSURLSessionDataTask *downloadFile = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:filePath] completionHandler:^(NSData *fileData, NSURLResponse *response, NSError *error){
        // .....
        //  fileData should return out.
    
    
          });
    [downloadFile resume];//NOTICE THE PLACEMENT HERE
          // I want to return the fileData after download completion.
          // how to return?
         }
    

    第二件事是,您可以简单地创建一个NSData 变量并在完成时为其分配值block,而不是将data 传回。

    只需在完成块中这样做

    if(fileData){
        return fileData;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-03
      • 1970-01-01
      • 2014-02-12
      • 2014-03-01
      • 1970-01-01
      • 2014-03-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多