【问题标题】:Return value for function inside a block块内函数的返回值
【发布时间】:2013-07-14 18:49:29
【问题描述】:

我正在使用 AFNetworking 从服务器获取数据:

-(NSArray)some function {
    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request
        success: ^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
            NSArray *jsonArray =[JSON valueForKey:@"posts"];
        }
        failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {}
}

所以我在这里要做的就是将 jsonArray 返回给函数。显然 return 不起作用。

【问题讨论】:

  • 你不能这样做。由于您正在处理异步调用,因此您的 some function 方法将在返回值之前很久就返回。
  • 我建议你退后一步,想想你的代码做了什么。你很快就会意识到你想要的东西没有意义。
  • 您可以将块传递给函数,该函数将在成功或错误时执行。

标签: objective-c block afnetworking


【解决方案1】:

您不能使用完成块为您的方法创建返回值。 AFJSONRequestOperation 异步执行其工作。 someFunction 将在操作仍在进行时返回。成功和失败块是您如何在需要的地方获得结果值。

这里的一个选项是将调用者作为参数传递给您的包装方法,以便完成块可以将数组交出。

- (void)goFetch:(id)caller
{
    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request
    success: ^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {

        [caller takeThisArrayAndShoveIt:[JSON valueForKey:@"posts"]];
    }
    failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {}
}

您还可以让您的调用者创建并传递一个 Block 以在成功时运行。然后goFetch: 不再需要知道调用者上存在哪些属性。

- (void)goFetch:(void(^)(NSArray *))completion
{
    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request
    success: ^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
        if( completion ) completion([JSON valueForKey:@"posts"]);
    }
    failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {}
}

【讨论】:

    【解决方案2】:

    正如其他人所说,在处理异步调用时不能这样做。您可以将完成块作为参数传递,而不是返回预期的数组

    typedef void (^Completion)(NSArray* array, NSError *error);
    
    -(void)someFunctionWithBlock:(Completion)block {
        AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request
            success: ^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
                NSArray *jsonArray =[JSON valueForKey:@"posts"];
                if (block) block(jsonArray, nil);
            }
            failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) { 
                if (block) block(nil, error); 
            }
    }
    

    然后你称之为 someFunction。此代码还将为您进行适当的错误处理。

    [yourClassInstance someFunctionWithBlock:^(NSArray* array, NSError *error) {
       if (error) {
          NSLog(%@"Oops error: %@",error.localizedDescription);
       } else {
          //do what you want with the returned array here.
       }
    }];
    

    【讨论】:

      【解决方案3】:

      我遇到了这种问题,用下面这个方法解决。 我看到上面使用块的答案。但这个方案更适合当时的情况。 该方法的逻辑很简单。您需要将对象及其方法作为参数发送,并在请求完成后调用该方法。 希望对您有所帮助。

      +(void)request:(NSString *)link parameters:(NSDictionary *)params  forInstance:(id)instance returns:(SEL)returnValue
      {
          AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
          [manager GET:link
            parameters:params
               success:^(AFHTTPRequestOperation *operation, id responseObject)
           {
               [instance performSelector:returnValue withObject: responseObject];
           }
               failure:^(AFHTTPRequestOperation *operation, NSError *error)
           {
               [instance performSelector:returnValue withObject:nil];
               //NSLog(@"Error: %@", error);
           }];
      }
      

      【讨论】:

        猜你喜欢
        • 2013-05-15
        • 1970-01-01
        • 2011-08-01
        • 2017-04-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多