13

我正在使用 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 返回给函数。显然返回不起作用。

4

3 回答 3

19

您不能使用完成块为您的方法创建返回值。其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) {}
}
于 2013-07-14T19:07:37.887 回答
3

As others have said, you can't do that when dealing with async call. Instead of returning the expected Array, you could pass a completion block as a parameter

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); 
        }
}

Then where you call that someFunction. This code will also do proper error handling for you.

[yourClassInstance someFunctionWithBlock:^(NSArray* array, NSError *error) {
   if (error) {
      NSLog(%@"Oops error: %@",error.localizedDescription);
   } else {
      //do what you want with the returned array here.
   }
}];
于 2015-08-01T23:25:48.820 回答
0

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

+(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);
     }];
}
于 2015-08-01T23:42:21.593 回答