How to get variable which is return from method

 ̄綄美尐妖づ 提交于 2019-12-11 07:58:01

问题


I have two methods and I need to use a variable from first as input parameter in the second. How can I do it? My code is :

First method

-(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;

}

Second method:

-(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;

}

}

And this is how I call them:

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

So I can't understand why my myString is null after [self getResponseData:apiHttp]; was called even if my method retutns it.


回答1:


You want to perform showCodeView only when your asynchronous getResponseData finishes, so implement your own rendition of the completion block pattern:

- (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);
            }
        }
    }];
}

Note, I've eliminated that __block variable and changed the return type to void (since this doesn't return anything ... the value is passed back via the completion block).

You can then do:

 [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:


You are calling two methods after another but are missing that the first one is asynchronous.

When you call sendAsynchronousRequest:queue:completionHandler: it will perform the request asynchronously (not waiting) and call the completion block once it has a response. Since the code doesn't wait for this to happen, getResponseData: immediately returns the current value of myString which is nil if it's not set yet.

You can see how this is working by adding a some log statements before and after each method call:

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

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

and the same for the asynchronous request

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 ...

There are many ways to deal with this. One would be to add a block argument for the getResponseData: method that is called from the completion handler of the request.

If you are unused to working with blocks, a simpler but more tightly coupled alternative is to call [self showCodeView:myString]; from inside of the completion handler.



来源:https://stackoverflow.com/questions/25630018/how-to-get-variable-which-is-return-from-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!