我正在使用AFNetworking进行POST请求。我需要等到完成块完成才能返回数据,我遇到了问题。
我有一个解决方案,直到我切换到AFNetworking:
int i = 0;
while (!done)
{
[NSRunLoop.currentRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
i++;
NSLog(@"While Loop:%i", i);
if (i == 149) //request timed out
done = YES;
}
现在,该解决方案偶尔会起作用。有时它只在NSLog(@"While Loop:%i", i);
仅记录1或2时完成,但有时它会记录到149并超时。似乎NSRunLoop
有时会在不同的线程中运行,但有时会在阻止我请求的同一线程上运行。
以下是我目前的代码:
- (id)postRequestWithBaseURLString:(NSString *)baseURLString function:(NSString *)function parameters:(NSDictionary *)parameters
{
if (baseURLString)
function = [baseURLString stringByAppendingString:function];
__block BOOL done = NO;
__block id returnObject = nil;
[self.manager POST:function parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSLog(@"Success: %@", responseObject);
done = YES;
returnObject = responseObject;
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(@"Error: %@", error);
done = YES;
}];
[manager.operationQueue waitUntilAllOperationsAreFinished];
int i = 0;
while (!done)
{
[NSRunLoop.currentRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
i++;
NSLog(@"While Loop:%i", i);
if (i == 149) //request timed out
done = YES;
}
return returnObject;
}
我尝试过dispatch_group
但没有成功。帮助
修改
好的,我有更多信息。当我第一次调用API时(例如,当我第一次调用ViewController
时),我的解决方案有效,但之后没有。也许,在加载视图之后,在与API调用相同的线程上调用while循环,从而阻塞它?
这似乎也很可能,因为在超时发生后几乎完全调用NSLog(@"Success: %@", responseObject);
。
答案 0 :(得分:5)
在线找到优雅的解决方案。我创建了自己的完成块。这是我做的:
+ (void)jsonRequestWithBaseURL:(NSString *)baseURL function:(NSString *)function parameters:(NSDictionary *)parameters completion:(void (^)(NSDictionary *json, BOOL success))completion
{
if (baseURL)
function = [baseURL stringByAppendingString:function];
NSLog(@"%@ function:%@, parameters:%@", self.class, function, parameters);
[AFHTTPRequestOperationManager.manager POST:function parameters:parameters success:^(AFHTTPRequestOperation *operation, id jsonObject)
{
//NSLog(@"Success: %@", jsonObject);
NSDictionary *jsonDictionary = (NSDictionary *)jsonObject;
if (completion)
completion(jsonDictionary, YES);
} failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(@"%@ AFError: %@", self.class, [error localizedDescription]);
completion(nil, NO);
}];
}
然后,当我需要调用该方法时,我这样做:
NSDictionary *parameters = @{@"email":@"me@example.com", @"password":@"mypassword"};
[ZAPRootViewController jsonRequestWithBaseURL:@"http://www.myserver.com/" function:@"login.php" parameters:parameters completion:^(NSDictionary *json, BOOL success)
{
if (success)
{
//do something
}
}];