【问题标题】:Facing an issue with NSURLSessionDataTask with SynchronousRequest in objective-c在 Objective-c 中使用 SynchronousRequest 面临 NSURLSessionDataTask 的问题
【发布时间】:2026-01-30 01:30:01
【问题描述】:

这是我使用NSURLConnection sendSynchronousRequest 的工作代码:

+ (Inc*)getData:(NSString*)inUUID {
    NSString* urlString = [NSString stringWithFormat:@"/inc/%@", incUUID];
    NSURLRequest* request = [[HttpRequest requestWithRelativePath:urlString] toNSMutableURLRequest];
    NSDictionary* json = [self getJSONForRequest:request];
    return [Inc incFromDictionary:json];
}  
+ (NSDictionary*)getJSONForRequest:(NSURLRequest*)request {
    NSData* responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    return  [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingAllowFragments error:nil];
}  

但是,sendSynchronousRequest:request 已被弃用。

所以,我使用了NSURLSessionDataTask而不是sendSynchronousRequest。这是我实现的代码:

+ (Inc*)getData1:(NSString*)inUUID {
    NSString* urlString = [NSString stringWithFormat:@"/in/%@", inUUID];
    NSURLRequest* request = [[HttpRequest requestWithRelativePath:urlString] toNSMutableURLRequest];
    //NSDictionary* json = [self getJSONForRequest1:request];
    __block NSDictionary* json;

    dispatch_async(dispatch_get_main_queue(), ^{
        [self getJsonResponse1:request success:^(NSDictionary *responseDict) {
            json = [responseDict valueForKeyPath:@"detail"];;
            //return [Inc incFromDictionary:json];

        } failure:^(NSError *error) {
            // error handling here ...
        }];
    });
    return [Inc incFromDictionary:json];
}  
+ (void)getJsonResponse1:(NSURLRequest *)urlStr success:(void (^)(NSDictionary *responseDict))success failure:(void(^)(NSError* error))failure
{
    NSURLSessionDataTask *dataTask1 = [[NSURLSession sharedSession] dataTaskWithRequest:urlStr completionHandler:^(NSData *data, NSURLResponse *response,
                                                                                                                   NSError *error) {
        NSLog(@"%@",data);
        if (error)
            failure(error);
        else {
            NSDictionary *json  = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
            NSLog(@"%@",json);
            success(json);
        }
    }];
    [dataTask1 resume];    // Executed First
}  

问题是在完成 api 调用之前,getData1 中的 return 语句调用。

提前致谢。

【问题讨论】:

  • dataTaskWithRequest 异步工作,你必须像getJsonResponse1 那样实现一个完成处理程序。实际上,您可以为两个处理程序传递相同的块对象。
  • 不明白。你能简单解释一下吗?
  • 即使我在 getJsonResponse1 中使用完成处理程序,它也不起作用。
  • getJsonResponse1 不会从方法 (void) 返回某些内容,而是调用完成块。您必须将相同的完成处理程序添加到 getData1
  • 你是说getData1中的NSURLSessionDataTask?

标签: objective-c nsurlrequest nsurlsessiondatatask sendasynchronousrequest


【解决方案1】:

如 cmets 中所述,您需要一个完成处理程序。

类似这样的东西(未经测试):

+ (void)getData1:(NSString*)inUUID success:(void (^)(NSDictionary *responseDict))success failure:(void(^)(NSError* error))failure {
    NSString* urlString = [NSString stringWithFormat:@"/in/%@", inUUID];
    NSURLRequest* request = [[HttpRequest requestWithRelativePath:urlString] toNSMutableURLRequest];

    [self getJsonResponse1:request success:^(NSDictionary *responseDict) {
        NSDictionary* json = [responseDict valueForKeyPath:@"detail"];
        success(json);

    } failure:^(NSError *error) {
        failure(error);
    }];
}


+ (void)getJsonResponse1:(NSURLRequest *)urlStr success:(void (^)(NSDictionary *responseDict))success failure:(void(^)(NSError* error))failure
{
    NSURLSessionDataTask *dataTask1 = [[NSURLSession sharedSession] dataTaskWithRequest:urlStr completionHandler:^(NSData *data, NSURLResponse *response,
                                                                                                                   NSError *error) {
        NSLog(@"%@",data);
        if (error)
            failure(error);
        else {
            NSDictionary *json  = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
            NSLog(@"%@",json);
            success(json);
        }
    }];
    [dataTask1 resume];    // Executed First
}

然后调用

[MyClass getData1:@"asdf" success:^(NSDictionary *responseDict) {
    dispatch_async(dispatch_get_main_queue(), ^{
        NSDictionary *json = [responseDict valueForKeyPath:@"detail"];
        Inc *inc = [Inc incFromDictionary:json];
        // do something witrh `inc`

    });
} failure:^(NSError *error) {
    // error handling here ...
}];

考虑使用类的实例和实例方法,而不仅仅是类方法。

【讨论】:

  • 感谢很多小改动,它就像一个魅力。