我有两种方法,我需要在第二种方法中使用第一个变量作为输入参数。我该怎么做?我的代码是:
第一种方法
-(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];
所以我无法理解为什么myString
null
被[self getResponseData:apiHttp];
调用后即使我的方法重新调整它也是如此。
答案 0 :(得分:2)
您正在调用两个方法,但是缺少第一个方法是异步的。
当您调用sendAsynchronousRequest:queue:completionHandler:
时,它将异步执行请求(不等待),并在响应完成后调用完成块。由于代码不会等待这种情况发生,getResponseData:
会立即返回myString
的当前值nil
,如果尚未设置的话。{/ p>
您可以通过在每次方法调用之前和之后添加一些日志语句来了解这是如何工作的:
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];
。
答案 1 :(得分: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];
}
}];