块内函数的返回值
Posted
技术标签:
【中文标题】块内函数的返回值【英文标题】: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
方法将在返回值之前很久就返回。
我建议你退后一步,想想你的代码做了什么。你很快就会意识到你想要的东西没有意义。
您可以将块传递给函数,该函数将在成功或错误时执行。
【参考方案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);
];
【讨论】:
以上是关于块内函数的返回值的主要内容,如果未能解决你的问题,请参考以下文章