Ios 如何将异步方法转换为同步方法
我正在从另一个方法调用一个方法。该方法在中间文件中存在。完成某些任务后,它将运行剩余的方法Ios 如何将异步方法转换为同步方法,ios,objective-c,asynchronous,semaphore,synchronous,Ios,Objective C,Asynchronous,Semaphore,Synchronous,我正在从另一个方法调用一个方法。该方法在中间文件中存在。完成某些任务后,它将运行剩余的方法 -(void)stateMethod{ [self.pickerView selectRow:0 inComponent:0 animated:YES]; lblTitle.text=@"State"; self.stateTF.text=@""; self.stateTF.inputView=_pickerView; [self.stateTF setInputA
-(void)stateMethod{
[self.pickerView selectRow:0 inComponent:0 animated:YES];
lblTitle.text=@"State";
self.stateTF.text=@"";
self.stateTF.inputView=_pickerView;
[self.stateTF setInputAccessoryView:toolBar];
NSString * method=@"***************************?countryID=";
NSString *urlString=[NSString stringWithFormat:@"%@%@%@",MAIN_URL,method,_countryId];
NSURL *url_ac=[[NSURL alloc]initWithString:urlString];
NSMutableURLRequest *request_ac=[[NSMutableURLRequest alloc]initWithURL:url_ac];
[request_ac setValue:loginUser.acessTokenStr forHTTPHeaderField:@"access_token"];
[NSURLConnection sendAsynchronousRequest:request_ac queue:[NSOperationQueue currentQueue] completionHandler:
^(NSURLResponse ac_response, NSData acData, NSError *connectionError) {
if (connectionError)
{
NSLog(@"ERROR CONNECTING DATA FROM SERVER: %@", connectionError.localizedDescription);
}
else {
dispatch_async(dispatch_get_main_queue(), ^{
NSString *responseString = [[NSString alloc] initWithData:acData encoding:NSUTF8StringEncoding];
[self parseStateListResult:acData];
});
}
}];
}
调用state方法时需要响应。基于状态方法响应,我在调用[self-statemethod]后正在执行一个任务。该任务需要“状态方法<代码>响应”。该任务在从state方法获取数据之前执行。
该方法在NSURLConnection`行之后退出。我想异步运行该方法。请帮帮我
我正在从另一个方法调用一个方法。该方法在中间文件中存在。完成某些任务后,它将运行剩余的方法
-(void)stateMethod{
[self.pickerView selectRow:0 inComponent:0 animated:YES];
lblTitle.text=@"State";
self.stateTF.text=@"";
self.stateTF.inputView=_pickerView;
[self.stateTF setInputAccessoryView:toolBar];
NSString * method=@"***************************?countryID=";
NSString *urlString=[NSString stringWithFormat:@"%@%@%@",MAIN_URL,method,_countryId];
NSURL *url_ac=[[NSURL alloc]initWithString:urlString];
NSMutableURLRequest *request_ac=[[NSMutableURLRequest alloc]initWithURL:url_ac];
[request_ac setValue:loginUser.acessTokenStr forHTTPHeaderField:@"access_token"];
[NSURLConnection sendAsynchronousRequest:request_ac queue:[NSOperationQueue currentQueue] completionHandler:
^(NSURLResponse ac_response, NSData acData, NSError *connectionError) {
if (connectionError)
{
NSLog(@"ERROR CONNECTING DATA FROM SERVER: %@", connectionError.localizedDescription);
}
else {
dispatch_async(dispatch_get_main_queue(), ^{
NSString *responseString = [[NSString alloc] initWithData:acData encoding:NSUTF8StringEncoding];
[self parseStateListResult:acData];
});
}
}];
}
它不在中间退出…sendAsynchronousRequest
调用后的部分是一个完成处理程序。这是一个单独的代码块,您将其传递到请求中,以便稍后运行。将其视为方法的一个参数,而不是stateMethod
代码的一部分
记住这一点,您可以看到stateMethod
确实会一直运行到最后,因为方法中的最后一行代码是sendAsyncronousRequest
调用
基于状态方法响应,我在调用[self-statemethod]后正在执行一个任务。该任务需要状态
方法响应一次。该任务在从state方法获取数据之前执行。该方法在NSURLConnection
行之后退出。我想异步运行该方法
因为您还没有给出需要响应的方法的名称,所以我们将其称为foo
。您的问题是请求是异步的,因此在响应可用之前调用foo
。处理该问题的一种方法是将对foo
的调用放在请求的完成块内,但您可能不想直接这样做,因为可能会从多个位置调用stateMethod
,其中只有一个随后调用foo
。相反,您可以更改stateMethod
,以便调用方可以指定完成块:
-(void)stateMethodWithCompletion:(nullable void (^)(NSURLResponse* response))stateCompletion {
[self.pickerView selectRow:0 inComponent:0 animated:YES];
lblTitle.text=@"State";
self.stateTF.text=@"";
self.stateTF.inputView=_pickerView;
[self.stateTF setInputAccessoryView:toolBar];
NSString * method=@"***************************?countryID=";
NSString *urlString=[NSString stringWithFormat:@"%@%@%@",MAIN_URL,method,_countryId];
NSURL *url_ac=[[NSURL alloc]initWithString:urlString];
NSMutableURLRequest *request_ac=[[NSMutableURLRequest alloc]initWithURL:url_ac];
[request_ac setValue:loginUser.acessTokenStr forHTTPHeaderField:@"access_token"];
[NSURLConnection sendAsynchronousRequest:request_ac queue:[NSOperationQueue currentQueue] completionHandler:
^(NSURLResponse ac_response, NSData acData, NSError *connectionError) {
if (connectionError) {
NSLog(@"ERROR CONNECTING DATA FROM SERVER: %@", connectionError.localizedDescription);
}
else {
if (stateCompletion != nil) {
stateCompletion(acResponse);
}
dispatch_async(dispatch_get_main_queue(), ^{
NSString *responseString = [[NSString alloc] initWithData:acData encoding:NSUTF8StringEncoding];
[self parseStateListResult:acData];
});
}
}];
}
这将替换旧的stateMethod
,但是如果您想要一个没有额外参数的版本,您也可以这样做:
-(void)stateMethod {
[self stateMethodWithCompletion:nil];
}
“编译器将方法保留在中间位置”?你是什么意思?我正在从另一个方法调用
stateMethod
。编译器将编译到NSURLConnection
行,然后退出该方法并执行该行后面的一些任务,即[self stateMethod]。再次输入此方法并执行剩余的行(即,在NSURLConnection
之后)。当您说“compiling”时,您确定不是指“running”。您似乎也对异步操作的概念感到困惑,因为您所描述的听起来是正确的;i、 e.连接在后台建立,当收到响应时调用完成处理程序。您说的是正确的。它只发生在应用程序运行时。我让调试器查看应用程序的流程,此时方法将在中间退出。但这是正确的。连接将在后台线程中发生,并且stateMethod
将退出。我尝试了你的代码。它也像以前一样工作。我已经得到了我想要的输出。在使用条件获得Url响应后,我将我的任务放置在stateMethod
中。感谢你的帮助。取决于你尝试执行的操作,您可能需要或想要在主线程上运行stateCompletion
块。如果是这样,将If(stateCompletion!=nil).
块移动到调度到主线程的块中。