2014-09-02 30 views
1

我有两个方法,我需要使用第一个变量作为第一个输入参数。我该怎么做?我的代码是:如何获得从方法返回的变量

第一种方法

-(NSString*)getResponseData :(NSString*) apiHttp { 


NSString *code = @"&code="; 
NSString *finalLink = [[NSString alloc] initWithFormat:@"%@%@",apiHttp,phoneNumber]; 
NSURLRequest *request = [NSURLRequest requestWithURL: 
         [NSURL URLWithString:finalLink]]; 
NSLog(@"%@", finalLink); 
__block NSDictionary *json; 
[NSURLConnection sendAsynchronousRequest:request 
            queue:[NSOperationQueue mainQueue] 
         completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 
          json = [NSJSONSerialization JSONObjectWithData:data 
                    options:0 
                    error:nil]; 
          NSLog(@"Async JSON: %@", json); 

          NSError *error; 
          NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; 

          myString = [jsonDict objectForKey:@"result"]; 
           // NSLog(@"%@", myString); 



       }]; 
return myString; 

} 

方法二

-(void)showCodeView:(NSString*) ifString{ 
if([ifString isEqualToString:@"200"]){ 
    aPasswordField.hidden = NO; 
    [aPasswordField setBorderStyle:UITextBorderStyleLine]; 
    aPasswordField.layer.cornerRadius=1.0f; 
    aPasswordField.layer.masksToBounds=YES; 
    aPasswordField.layer.borderColor=[[UIColor whiteColor]CGColor]; 
    aPasswordField.layer.borderWidth= 0.8f; 
    UIColor *color = [UIColor lightTextColor]; 
    aPasswordField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"Код" attributes:@{NSForegroundColorAttributeName: color}]; 
    self.aPasswordField.delegate = self; 

} 

}

这是我怎么称呼他们:

[self getResponseData:apiHttp]; 
[self showCodeView:myString]; 

所以我不明白为什么我的myStringnull[self getResponseData:apiHttp];被称为即使我的方法反驳它。

回答

1

要执行showCodeView,只有当你的异步getResponseData完成,因此实现自己完成块模式的再现:

- (void)getResponseData :(NSString*) apiHttp completionHandler:(void (^)(NSDictionary *, NSError *))completion { 
    NSString *code = @"&code="; 
    NSString *finalLink = [[NSString alloc] initWithFormat:@"%@%@",apiHttp,phoneNumber]; 
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:finalLink]]; 
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 
     if (completion) { 
      if (connectionError) { 
       completion(nil, connectionError); 
      } else { 
       NSError *parseError; 
       NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError]; 
       completion(json, parseError); 
      } 
     } 
    }]; 
} 

注意,我已经消除了__block变量,改变了返回类型void (因为这不会返回任何东西...该值通过完成块传回)。

你可以再做:

[self getResponseData:apiHttp completionHandler:^(NSDictionary *json, NSError *error) { 
    if (error) { 
     // handle this however appropriate for your app 
    } else { 
     NSString *myString = json[@"result"]; 
     [self showCodeView:myString]; 
    } 
}]; 
2

您正在调用两个接一个的方法,但缺少第一个方法是异步的。

当您调用sendAsynchronousRequest:queue:completionHandler:时,它将异步执行请求(不等待),并在有响应后调用完成块。由于代码不会等待这种情况发生,因此getResponseData:立即返回当前值myString,如果它尚未设置,则返回nil

你可以看到这是如何之前和之后每个方法调用添加一些日志报表工作:

NSLog(@"Before getResponseData:"); 
[self getResponseData:apiHttp]; 
NSLog(@"After getResponseData:"); 

NSLog(@"Before showCodeView:"); 
[self showCodeView:myString]; 
NSLog(@"After showCodeView:"); 

与同为异步请求

NSLog(@"Before sendAsynchronousRequest:"); 
[NSURLConnection sendAsynchronousRequest:request 
            queue:[NSOperationQueue mainQueue] 
         completionHandler:^(NSURLResponse *response, 
              NSData *data, 
              NSError *connectionError) { 
          NSLog(@"After sendAsynchronousRequest:"); 
          // the rest of the completion block ... 

有许多方法来处理这个问题。一种方法是为从请求的完成处理程序调用的getResponseData:方法添加块参数。

如果您不习惯使用块,则更简单但更紧密的替代方法是从完成处理程序内部调用[self showCodeView:myString];