得到的数据如何直接赋值给外部变量?

得到的数据如何直接赋值给外部变量?


在外面声明了一个字符串变量register_token,然后在task里面打印是有值得,在外面打印是null,必须要再创建一个model吗,我就想拿到这个regi_token的值


        //创建会话任务
        NSURLSessionDataTask *task1 = [session dataTaskWithRequest:rq_send_code completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            // 判断是否请求成功
            if (error) {
                NSLog(@"post error :%@",error.localizedDescription);
            }else {
               
                
                // 如果请求成功,则解析数据。
                id object = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error];
                // 判断是否解析成功
                if (error) {
                    NSLog(@"post error :%@",error.localizedDescription);
                }else {
                    // 解析成功,处理数据,通过GCD获取主队列,在主线程中刷新界面。
                    NSLog(@"post success :%@",object);
                    dispatch_async(dispatch_get_main_queue(), ^{
                        // 刷新界面...
                    });


                        //得到验证码的标识符
                        id id_code = [(NSDictionary *)object objectForKey:@"data"];
                        register_token = [(NSDictionary *)id_code objectForKey:@"register_token"];
                        NSLog(@"------------------%@",register_token);                }
                

            }}];
        
        //执行任务
        [task1 resume];
        
        NSLog(@"------------------%@",register_token);

正在回答

登陆购买课程后可参与讨论,去登陆

9回答

1、首先说一下产生这个问题的原因:因为是异步线程,所以定一个全局变量在网络请求回来后的进行数据赋值,然后在主线程中打印,你会发现,这个全局变量是空值。因为异步线程消耗的时间是十秒,而主线程的执行时间是1秒,那么在主线程中不断打印,全局变量里面怎么可能有值,就会是空值。

2、解决方法:重写set方法,再set方法里打印。



  • 司空琪 提问者 #1
    老师,我刚刚试着用set方法,但每次刚运行到set方法时程序就会崩溃,具体内容的我截图发到上面了,麻烦老师再帮我看一下
    2018-08-27 18:45:02
提问者 司空琪 2018-08-27 20:32:49
  • 在子线程中获取数据以后,在调用回到主线程的方法[self performSelectorOnMainThread:@selector(getData) withObject:nil waitUntilDone:NO];定义一个getData方法,在方法中输出code_token
    2018-08-28 09:45:04
提问者 司空琪 2018-08-27 20:30:06
提问者 司空琪 2018-08-27 20:29:28

http://img1.sycdn.imooc.com//climg/5b83ee1d0001b18511770250.jpg

还是不行,卡这里三天了,着急啊啊啊。。。。。。老师,您还有别的办法吗,关于提取post请求返回的数据的

提问者 司空琪 2018-08-27 18:48:58


http://img1.sycdn.imooc.com//climg/5b83d69c0001eafd06490395.jpg

声明变量和set,get方法

http://img1.sycdn.imooc.com//climg/5b83d69c00015a4807390263.jpg

实现这两个方法

http://img1.sycdn.imooc.com//climg/5b83d69c000190ea04540244.jpg

在网络请求中调用set方法

  • set方法中不需要通过self调用code_token,直接code_token=new_code_token就可以了。get方法直接是-(NSString *)code_token;
    2018-08-27 19:26:11
  • 提问者 司空琪 回复 Tender10 #2
    老师,set方法没有执行是为什么啊,情况如上图,我这请求是写在一个函数里的,视图控制器中有一个按钮,点击按钮会调用这个函数,然后在函数里写了网络请求和弹出下一个界面这些东西
    2018-08-27 20:35:24
提问者 司空琪 2018-08-27 14:59:45

这些是关于网络请求的所有代码内容,viewcontroller中有个按钮,按钮的响应方法就是这个-(void)send_verification_code函数;最后面的是打印的内容


@interface RegisteredWindowViewController (){
    NSString *register_token;  
}
- (void)viewDidLoad {
    [super viewDidLoad];
    register_token = [[NSString alloc]init];
}

-(void)send_verification_code{
    
    //拿到手机号
    [regist_tf_phonenumber resignFirstResponder];
    NSString *phone_number = [regist_tf_phonenumber.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
    
    if(phone_number.length!=11){
        [self showAlert:@"提示" message:@"请输入正确的手机号"];
    }
    else{
        
    //请求发送验证码

        NSURL *url_yj_sendcode = [NSURL URLWithString:@"http://123.207.85.37:8080/user/register_a.do"];
        NSDictionary *parametersDict = @{@"token":@"sendCode",@"phone":phone_number};
        
        
        //创建request请求
        NSMutableURLRequest *rq_send_code = [NSMutableURLRequest requestWithURL:url_yj_sendcode];
        
        //以“key=value&”的方式创建请求体
        NSMutableString *parameterString = [[NSMutableString alloc]init];
        int pos =0;
        for (NSString *key in parametersDict.allKeys) {
            // 拼接字符串
            [parameterString appendFormat:@"%@=%@", key, parametersDict[key]];
            if(pos<parametersDict.allKeys.count-1){
                [parameterString appendString:@"&"];
            }
            pos++;
        }
        //        NSLog(@"%@",parameterString);
        NSData *parametersData = [parameterString dataUsingEncoding:NSUTF8StringEncoding];
        //设置请求参数
        [rq_send_code setHTTPMethod:@"POST"];
        [rq_send_code setTimeoutInterval:8.0];
        [rq_send_code setHTTPBody:parametersData];
        
        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
        
        NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
        
        
        
        //创建会话任务
        NSURLSessionDataTask *task = [session dataTaskWithRequest:rq_send_code completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            // 判断是否请求成功
            if (error) {
                NSLog(@"post error :%@",error.localizedDescription);
            }else {
                // 如果请求成功,则解析数据。
                id object = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error];
                // 判断是否解析成功
                if (error) {
                    NSLog(@"post error :%@",error.localizedDescription);
                }else {
                    // 解析成功,处理数据,通过GCD获取主队列,在主线程中刷新界面。
                    NSLog(@"post success :%@",object);
                    dispatch_async(dispatch_get_main_queue(), ^{
                        // 刷新界面...
                    });
                    
                    id id_code = [(NSDictionary *)object objectForKey:@"data"];
                    
                    NSLog(@"请求体内部打印:%@",id_code);
                    
                    self->register_token =[(NSDictionary *)id_code objectForKey:@"register_token"];
                    
                    NSLog(@"请求体内部打印:%@",self->register_token);
                    
                }
            }
            
        }];
        
        //执行任务
        [task resume];
        
        
        NSLog(@"请求体外部打印:%@",self->register_token);
    }
}

@end


打印的内容:
2018-08-27 14:47:39.337542+0800 语境[44249:2504477] 请求体外部打印:
2018-08-27 14:47:39.399943+0800 语境[44249:2504477] Can't find keyplane that supports type 4 for keyboard iPhone-PortraitTruffle-NumberPad; using 6919991127445953680_PortraitTruffle_iPhone-Simple-Pad_Default
2018-08-27 14:47:39.539340+0800 语境[44249:2504579] [] nw_proxy_resolver_create_parsed_array PAC evaluation error: NSURLErrorDomain: -1004
2018-08-27 14:47:39.573061+0800 语境[44249:2504582] post success :{
    data =     {
        "register_token" = F1A91D7460E3F7EBED719AEFB2AEC8DC;
    };
    msg = "\U53d1\U9001\U6210\U529f!";
    status = 200;
}
2018-08-27 14:47:39.573354+0800 语境[44249:2504582] 请求体内部打印:{
    "register_token" = F1A91D7460E3F7EBED719AEFB2AEC8DC;
}
2018-08-27 14:47:39.573580+0800 语境[44249:2504582] 请求体内部打印:F1A91D7460E3F7EBED719AEFB2AEC8DC
2018-08-27 14:49:39.460370+0800 语境[44249:2504582] Received XPC error Connection interrupted for message type 3 kCFNetworkAgentXPCMessageTypePACQuery

提问者 司空琪 2018-08-27 11:39:15

老师,我刚刚试了一下把数据存储到本地的方法,但是每次读取时都是上次存入的数据,而不是本次请求返回的数据,在这里卡了好久了,到底该怎么做啊,老师

提问者 司空琪 2018-08-27 10:41:05

上面这些都是写在一个方法里面,进入方法后声明定义的register_token

-(void)input_verification_code{
    
    __block  NSDictionary *register = [[NSDictionary alloc]init];


......


}

  • 提问者 司空琪 #1
    感觉block里的东西每次都是最后才执行的,拿不出post请求返回的数据
    2018-08-27 10:43:17
  • Tender10 回复 提问者 司空琪 #2
    你把register_token这样接收数据的变量定义成全局变量
    2018-08-27 13:48:59
  • 提问者 司空琪 回复 Tender10 #3
    我是过来,没用啊,在内部可以打印出来,然后在外面打出来就是空值
    2018-08-27 13:51:00
Tender10 2018-08-27 10:02:19

这跟作用域有关系,你的register_token在哪里声明定义的。

  • 提问者 司空琪 #1
    我在viewdidload里,函数里,block代码块里都试过,没有效果啊,那究竟post请求返回的数据要怎么使用啊,难道只能打印出来?不能传出去吗
    2018-08-27 11:46:55
  • 提问者 司空琪 #2
    还是说得用其他的网络请求方法?
    2018-08-27 11:49:03
  • 提问者 司空琪 #3
    用信号量来阻塞线程的方法可以实现同步获取数据吗
    2018-08-27 12:01:26
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
iOS提升:网络多线程与常用主流框架
  • 参与学习       150    人
  • 解答问题       94    个

搞定网络多线程,掌握动画特效,熟悉第三方库等实用技术的使用,更有最新swift UI控件的讲解,让您不断丰富自己的开发技能。

了解课程
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师