我正在使用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时(例如,当我第一次调用a时ViewController
),我的解决方案有效,但之后没有.也许,在加载视图之后,在与API调用相同的线程上调用while循环,因此阻塞它?
这似乎也很可能,因为NSLog(@"Success: %@", responseObject);
在超时发生后几乎完全被调用.
在线找到优雅的解决方案.我创建了自己的完成块.这是我做的:
+ (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 } }];