2014-09-02 31 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];