• block传值以及利用block封装一个网络请求类


    1.block在俩个UIViewController间传值

    近期刚学了几招block 的高级使用方法,事实上就是利用block语法在俩个UIViewController之间传值,在这里分享给刚開始学习的人,同一时候也方便我自己理解。

    我们知道UINavigationController类管理UIViewController的时候,利用的是“栈”的思想,在这里不做过多解释,切入正题。如果我们如今有俩个UIViewController,viewC1和viewC2。viewC1比viewC2先进入到UINavigationController里,即viewC2是由viewC1push出来的。这里的传值是指将viewC2的值传到viewC1里面。比如通讯录的改动,微信里改动信息等。

    不多说。直接上样例:

    一.首先在viewC2的头文件里的代码: 

    //1 。

    重定义一个block类型 typedef void(^BL)(UIColor *color); typedef void(^stringBL)(NSString *string); @interface SecondViewController : UIViewController //定义一个block属性 一定要使用copy特性 原因: @property (nonatomic, copy) BL block; @property (nonatomic, copy) stringBL string; - (void)valueBlock:(BL)block; - (void)valueStringBlock:(stringBL)block;

    提示:

    重定义block在Xcode中有快捷实现方式,直接在@interfacexxx 上面一行打typedef会有提示: 直接回车,第一个參数是返回值类型,第二个为重定义的block名称,第三个为要传參数类型和參数名。然后须要定义重定义block类型的属性。而且实现參数为该重定义类型block的方法。

    二.viewC2的.m文件里代码:

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
        button.frame = CGRectMake(0, 70, 320, 40);
        [self.view addSubview:button];
        [button setTitle:@"return 1 page" forState:UIControlStateNormal];
        [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
    }
    - (void)buttonAction:(UIButton *)button
    {
    //    2.在合适的地方运行block代码
        self.block([UIColor redColor]);
        self.string(@"asdasdasd");
        [self.navigationController popToRootViewControllerAnimated:YES];
    }
    - (void)valueBlock:(BL)block
    {
        self.block = block;
    }
    - (void)valueStringBlock:(stringBL)block
    {
        self.string = block;
    }
    
    解释:实现头文件里定义的方法,方法内部写将參数赋值给重定义block的属性,然后在合适的地方运行block代码,block里面的參数即你要传的值。

    三.在viewC1中push第二个页面的时候调用 viewC2的方法,直接回车。block重定义中的參数名里存的即是要在viewC1中改动的值。


    2.利用block封装网络请求类。

    1.创建网络请求类NetRequest,头文件例如以下
    typedef void(^BLOCK)(id result);
    
    @interface NetRequest : NSObject
    @property (nonatomic, copy) BLOCK bl;
    - (void)requestNetWithUrl:(NSString *)urlStr BodyOfRequestForString:(NSString *)bodyStr block:(BLOCK)bl;
    + (void)PostWithUrl:(NSString *)urlStr BodyOfRequestForString:(NSString *)bodyStr block:(BLOCK)bl;
    @end
    
    解释:该处利用的是异步post传值。头文件写法基本上跟block传值一样,我这里写了一个+号方法,为的是能在使用NetRequest类的时候更加方便。

    能够看到这里的方法有三个參数,各自是url的地址。以及设置request的HttpBody属性的。这里属于网络请求,不做过多解释。

    2.以下看.m文件:实现俩个方法
    - (void)requestNetWithUrl:(NSString *)urlStr BodyOfRequestForString:(NSString *)bodyStr block:(BLOCK)bl
    {
        self.bl = bl;
        NSURL *url = [NSURL URLWithString:urlStr];
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30];
        request.HTTPMethod = @"post";
        NSData *bodyData = [bodyStr dataUsingEncoding:NSUTF8StringEncoding];
        request.HTTPBody = bodyData;
        [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
           NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options :NSJSONReadingMutableContainers error:nil];
            NSLog(@"%d", [[dic objectForKey:@"news"] count]);
            self.bl(dic);
            
    }];
        
    }
    + (void)PostWithUrl:(NSString *)urlStr BodyOfRequestForString:(NSString *)bodyStr block:(BLOCK)bl
    {
        NetRequest *netRequest = [[NetRequest alloc] init];
        [netRequest requestNetWithUrl:urlStr BodyOfRequestForString:bodyStr block:bl];
    }
    解释:-方法中首先要设置属性block=參数block。再将要传的值加入到block方法的參数中。+号方法是利用-号方法将參数block传给属性block。由于在+号方法中不能直接给属性赋值。


    3.怎样使用:将传输数据到ViewController上
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    {
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        if (self) {
            // Custom initialization
            self.array = [NSMutableArray array];
            self.title = @"新闻";
            NSString *urlStr = @"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx";
            NSString *bodyStr = @"date=20131129&startRecord=1&len=30&udid=1234567890&terminalType=Iphone&cid=213";
            [NetRequest PostWithUrl:urlStr BodyOfRequestForString:bodyStr block:^(id result) {
                self.array = [result objectForKey:@"news"];
                [self.tableView reloadData];
            }];
        }
        return self;
    }
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 480) style:UITableViewStylePlain];
        [self.view addSubview:self.tableView];
        self.tableView.dataSource = self;
        self.tableView.delegate = self;
        [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"reuse"];
        
    }
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        NSString *str = @"reuse";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:str];
        cell.textLabel.numberOfLines = 2;
        cell.textLabel.text = [[self.array objectAtIndex:indexPath.row] objectForKey:@"title"];
        return cell;
    }
    -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        WebViewController *webVC = [[WebViewController alloc] init];
        webVC.webUrl = [[self.array objectAtIndex:indexPath.row] objectForKey:@"newsUrl"];
        [self.navigationController pushViewController:webVC animated:YES];
        [webVC release];
    }
    
    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return [self.array count];
    }


    以下来看看为什么我们要用这样的传值方式:由于我要把当前获得的传输数据给一个UIViewController,而这个UIViewController上面有UITableView。须要刷新,而我们获取网络数据的时候使用的是利用block封装的一个获取NSData的方法。该方法会在数据载入完后才会运行块语句,并且网络会有延迟,我们的UI界面会优先于数据显示在手机上,所以当数据请求成功后,我们须要刷新页面,即调用UITableView的reloadData方法,所以才使用这样的策略。

    这是今天新get的技能,在这里分享给大家,我是个新手 我的QQ 263506069,上面有问题还望能得到大家的指导。

    谢谢!

  • 相关阅读:
    Redis 3.2 版本后 list 的实现
    每当发生一次垃圾收集,所有用户线程都必须跑到最近的一个安全点然后挂起线程来等待垃圾回收
    你了解dt.jar吗
    spring boot + vue + element-ui全栈开发入门——开篇
    玩转spring boot——开篇
    java结合node.js非对称加密,实现密文登录传参——让前后端分离的项目更安全
    零门槛,包教会。让你在5分钟内使用以太坊ERC20智能合约发行属于自己的空气币
    spring boot高性能实现二维码扫码登录(下)——订阅与发布机制版
    spring boot高性能实现二维码扫码登录(中)——Redis版
    spring boot高性能实现二维码扫码登录(上)——单服务器版
  • 原文地址:https://www.cnblogs.com/cxchanpin/p/7250028.html
Copyright © 2020-2023  润新知