我如何 return 从块中捕获的变量到 Objective-C 中的调用者

How do I return variables captured from a block to the caller in Objective-C

我在 return 将在块中捕获的异步 response/error 对返回给调用方时遇到问题。这是代码:

- (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error
{
    __block NSData* b_data = nil;
    __block NSURLResponse* b_response = nil;
    __block NSError* b_error = nil;

    dispatch_semaphore_t wait = dispatch_semaphore_create(0);

    [self sendRequest:request completion:^(NSHTTPURLResponse* c_response, NSData* c_data, NSError* c_error) {

        b_data = c_data;
        b_response = c_response;
        b_error = c_error;

        dispatch_semaphore_signal(wait);
    }];

    dispatch_semaphore_wait(wait, DISPATCH_TIME_FOREVER);

    response = &b_response; // ERROR: Assigning NSURLResponse *__strong * to NSURLResponse *__autoreleasing * changes retain/release properties of pointer
    error = &b_error;       // ERROR: Assigning NSError *__strong * to NSError *__autoreleasing * changes retain/release properties of pointer

    return b_data;
}

基本上,我正在将异步请求转换为同步请求。我需要通过指向指针的指针将 return 和 response/error 对返回给调用者。但是,我 运行 遇到了 ARC 和块的一些问题。

我想将 response/error 复制出块并 return 将其复制到调用者而不更改方法签名(有大量遗留代码调用此方法 - 我'我正在尝试小心翼翼地用 NSURLSession 替换 NSURLConnection。

有什么好的方法可以提取结果并将它们 return 给调用者?

您的两个错误与该块无关。这些行应该是:

if (response) {
    *response = b_response;
}
if (error) {
    *error = b_error;
}

如果调用者为参数传递 nil,则需要进行 if 检查。尝试取消引用 nil 指针时会发生崩溃。

也没有必要将 response/error 对复制到本地 __block 变量。你可以在检查nil后直接将它们写入参数。