美文网首页iOS 开发iOS异步多线程IOS知识整理
Block从入门到放弃宝典(一):block的基本使用

Block从入门到放弃宝典(一):block的基本使用

作者: 键盘风筝 | 来源:发表于2016-09-27 16:01 被阅读880次

    通过这几天大家的反馈,感觉大家对Block和内存泄漏的呼声很高,本来想这次写runtime在实际项目中的用法,不过想一想还是先满足大家的欲望吧.接下来的一段时间,我会由浅入深的讲解一下Block和内存泄漏,让大家学习Block有一个阶段性和成体系性,不过我的风格还是以项目的可操作性为主,喜欢的可以点一波关注

    写之前我上网搜了一下block,大多数都讲的是block的底层实现,很多人看的云里雾里的,我会由简入难,先给大家讲面向oc的block,底层实现会在基础都讲完了,为大家深入讲解,小伙伴觉得我的安排怎么样.

    iOS4.0开始,Block横空出世,自他出生开始,就深受Apple和开发者的喜爱.他其实就是c预言的补充,书面点说就是带有自动变量的匿名函数.其实很多初级开发者也很喜欢使用Block,第一呢感觉他很简洁,代码的可读性也高,第二确实无形中提升了代码的逼格,但是殊不知自己有很多循环引用的问题,所以说还是劝大家理解透彻了,再在项目中使用.

    这一次给大家介绍Block的基本类型和项目中的实际操作

    Block的格式


    格式.png

    Block的基本类型

    1.无参数无返回值
    void(^tempBlock)() = ^(){
            NSLog(@"无参无返回值");
        };
    //调用
    tempBlock();
    
    2.无参数有返回值
    int(^tempBlock)() = ^(){
            return 10;
        };
    //调用的时候,无论你输入的是什么都返回的是10;
    tempBlock(100);
    
    3.有参数无返回值
    void(^tempBlock)(int) = ^(int temp){
            NSLog(@"有参数无返回值");
        };
    
    4.有参数有返回值
    int(^tempBlock)(int) = ^(int number){
            return number;
        };
    //输入多少打印就是多少
    tempBlock(100);
    

    Block的经典实用场景

    1.修改外部变量
    __block int x = 100;
    void(^sumXWithYBlock)(int) = ^(int y){
          x = x + y;
          NSLog(@"new value %d",x);
     };
    打印的值就是x+y,100+100=200
    sumXWithYBlock(100);
    
    2.页面间的传值
    • 1.在第二个页面(SecondViewController)首先声明一个属性
    /**
     先声明block的名字,并确定参数的类型
     */
    @property(nonatomic,copy)void (^netViewBlock)(NSString *text);
    
    • 2.在点击按钮返回的时候,往回传你需要传的参数,参数类型要一致
    -(void)back{
        self.netViewBlock(@"你好");
        [self.navigationController popViewControllerAnimated:YES];
    }
    
    • 3.在第一页(FirstViewController),准备push进入下一页的时候,获取ViewController2的属性,并实现.
    -(void)click:(UIButton *)sender{
    //把第二页的返回的值显示在label上
        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(30, 100, 200, 30)];
        [self.view addSubview:label];
        SecViewController *vc = [[SecViewController alloc] init];
        vc.netViewBlock = ^(NSString *text){
            label.text = text;
        };
        [self.navigationController pushViewController:vc animated:YES];
    }
    
    3.自定义Block

    例子:点击Button,需要改变Button的title
    实现:
    1.创建一个工具类,声明一个类方法,并自定义一个block,需要传title,所以传参类型是NSString

    @interface ChangeBuTitleTool : NSObject
    +(void)changeBuTitleWithText:(void(^)(NSString *titleText))text;
    @end
    

    2.实现

    @implementation ChangeBuTitleTool
    +(void)changeBuTitleWithText:(void(^)(NSString *titleText))text{
        if (text) {
            text(@"键盘风筝");
        }
    }
    @end
    

    3.在控制器里Button的点击的时候,实现改变title的方法

    -(void)addButton{
        UIButton *bu = [UIButton buttonWithType:(UIButtonTypeCustom)];
        bu.backgroundColor = [UIColor blueColor];
        bu.frame = CGRectMake(30, 90, 100, 50);
        [self.view addSubview:bu];
        [bu addTarget:self action:@selector(click:) forControlEvents:(UIControlEventTouchUpInside)];    
    }
    
    -(void)click:(UIButton *)sender{
        [ChangeBuTitleTool changeBuTitleWithText:^(NSString *titleText) {
            [sender setTitle:titleText forState:(UIControlStateNormal)];
        }]; 
    }
    
    5.Block与typedef的结合

    在上一个例子中,声明一个类方法,其中定义block直接写在类方法里,看起来很不和谐,尤其是对新手看起来可读性不太高,可以用typedef单独定义一个block,增加代码的可读性

    //这样看起来是不是整洁多了
    typedef void(^titleBlock)(NSString *titleText);
    @interface ChangeBuTitleTool : NSObject
    +(void)changeBuTitleWithText:(titleBlock)text;
    //+(void)changeBuTitleWithText:(void(^)(NSString *titleText))text;
    @end
    
    @implementation ChangeBuTitleTool
    +(void)changeBuTitleWithText:(titleBlock)text{
        if (text) {
            text(@"键盘风筝");
        }
    }
    @end
    

    第一节讲完了demo下载,小伙伴们第二节想知道关于block的什么呢?小伙伴们留言起来吧,我会尽可能满足大家的.

    相关文章

      网友评论

        本文标题:Block从入门到放弃宝典(一):block的基本使用

        本文链接:https://www.haomeiwen.com/subject/xgucyttx.html