• block总结


    1.是什么?

    一种特殊的数据类型

    2.有什么用?

    用于保存代码块

    3.怎么用?

    >1.声明block的快捷键:

    inlineBlock

    >2.block的声明:

        <#returnType#>(^<#blockName#>)(<#parameterTypes#>) = ^(<#parameters#>) {
            <#statements#>
        };

    >3.声明/初始化/调用

        //声明
        void(^myBlock1)();//无参无反
        int(^myBlock2)();//无参有反
        void(^myBlock3)(int);//有参无反
        int(^myBlock4)(int,int);//有参有反
    
        //初始化
        myBlock1 = ^()
        {
            NSLog(@"无参无反");
        };
    
        myBlock2 = ^()
        {
            return 3;
        };
    
        myBlock3 = ^(int a)
        {
            NSLog(@"%d",a);
        };
    
        myBlock4 = ^(int a,int b)
        {
            return a + b;
        };
    
        //调用
        myBlock1();
        int num = myBlock2();
        myBlock3(3);
        int sum = myBlock4(3,4);

    >4.给block起别名

    返回值类型 (^别名)(参数);

    例:

    typedef void(^myBlock)();//给第一个无参无反的block起别名myBlock,myBlock就称为一种数据类型

    使用:

      myBlock block1 = ^(){
            NSLog(@"声明和定义不同,声明仅仅是声明一个变量(开辟一块内存空间),并不初始化,定义包含了初始化,像这样即是声明的同时初始化了");
        };

    像这样仅仅是声明了一个myBlock类型的变量:

        myBlock block2;
        myBlock block3;
        myBlock block4;

    因为block是一种数据类型,因此数据类型所具有的所用特性block都具有,可以声明变量;作为参数;作为返回值;

    >5.block作为函数参数

    >例一:

    typedef int(^myBlock2)();
    typedef int(^myBlock3)(int);
     int sum(myBlock2 m,myBlock3 n,int a)//a为myBlock3需要的参数
    {
    //    int num1 = m();
    //    int num2 = n(a);
    //    return num1 + num2;
        return m() + n(a);
    }
        //block作为函数参数
        myBlock2 m = ^(){
            return 10;
        };
    
        myBlock3 n = ^(int a)
        {
            return a;
        };
    
        int num = sum(m, n, 10);
    
        NSLog(@"%d",num);//输出20;

    此种方式并不常用.常用的情景是:比如有三个函数,开头和结尾部分执行的代码一样,中间有部分代码不同,那么就可以将中间部分抽取为block,将三个函数变为一个,调用三次该函数,传入不同的block即可.

    >例二:

     
    void test1() {
    
        NSLog(@"AAAAAAAAAAAAAAAAAAAA");
        
        NSLog(@"星期天,今天去哪儿浪呢?");
        
        NSLog(@"BBBBBBBBBBBBBBBBBBBB");
        
        
    }
    
    void test2() {
        
        NSLog(@"AAAAAAAAAAAAAAAAAAAA");
        
        NSLog(@"星期一,昨天玩的好累不想上班.");
        
        NSLog(@"BBBBBBBBBBBBBBBBBBBB");
        
    }
    
    void test3() {
        
        NSLog(@"AAAAAAAAAAAAAAAAAAAA");
        
        NSLog(@"星期二,昨天的任务还没完成");
        
        NSLog(@"BBBBBBBBBBBBBBBBBBBB");
        
    }

    通过block优化,分析中间部分代码,不需要参数,返回值,定义无参无反的block:

    typedef void(^myBlock)()

    将四个函数抽取为一个

    void test(myBlock myLife) {
        
        NSLog(@"AAAAAAAAAAAAAAAAAAAA");
        
      if(myLife){//判断block是否为nil,否则可能报错,会报什么错呢?,为什么是nil呢,nil不是用于OC对象为空的情况么?block是基本数据类型?还是OC类型?
    myLife();
      } NSLog(
    @"BBBBBBBBBBBBBBBBBBBB"); }

    main函数中就可以这样写:

     test(^(){
         NSLog(@"星期天,今天去哪儿浪呢?");
     });
     test(^(){
         NSLog(@"星期一,昨天玩的好累不想上班.");
     });
     test(^(){
         NSLog(@"星期二,昨天的任务还没完成");
     });

    >6.作为函数返回值

    typedef void(^myBlock)();
    
    myBlock test4()
    {
        return ^(){
    
        };
    }

    >7.利用block在不同对象间进行传值

    假设A需要传值给B,那么需要在A中定义一个block属性,在需要的时候传递值,先判断是否为nil,不为nil则调用block.

    需要在B中声明一个属性(有东西接收就可以,不一定就要定义属性),用以接收传递过来的值,B必须拿到A,比如A成为B的属性,那么就可以获取A的block属性,并定义,判断的时候,block就已经定义了,就可以实现传值了.

    例子:

    控制器的View上有一个绿色的View,当点击屏幕的时候,传递一个NSInteger数据给控制器.

    分析:

    绿色的View为数据的传递者,控制器为接收者,因此,需要给绿色的View声明一个block类型的属性,因此自定义一个GreenView的类用于描述绿色的View,并在其中声明block属性

    typedef void(^GreenViewBlock)(NSInteger index);
    @property (nonatomic,copy) GreenViewBlock myBlock;

    当点击屏幕的时候传递数据,因而重写touchesBegin方法

    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        if (_myBlock) {//如果实现了,就调用
            _myBlock(11);
        }
    }

    控制器为接收者,因而给控制器声明一个属性用于接收数据,又因为,需要在控制器中初始化block,这样点击屏幕是block不为nil,实现传值,因而需要获得绿色的View的属性block,因而,将绿色的View拖成控制器的属性

    @property (nonatomic,assign) NSInteger index;
    
    @property (weak, nonatomic) IBOutlet GreenView *greenView;
    //初始化block  
    _greenView.myBlock = ^(NSInteger index){ self.index = index; };
    //上面的赋值操作即是调用index的setter方法,因而此时即可获得传递过来的数据
    - (void)setIndex:(NSInteger)index { _index = index; NSLog(@"%ld",index); }

    >8.注意:

     block内部默认不能修改外部的局部变量

     用__block修饰局部变量,在block中就可以访问了.

     

  • 相关阅读:
    重新整理汇编 系列文章
    bat使用forfiles自动批量删除过期文件
    bat文件去掉变量字符串前、中、后的空格
    【Bluetooth蓝牙开发】一、开篇词 | 打造全网最详细的Bluetooth开发教程
    京东云开发者|代码评审的价值和规范
    动态鲜花网页的实现
    Java代码规范,一文带你了解 Alibaba COLA 架构
    手把手教你复活Google翻译
    开发H5程序或者小程序的时候,后端Web API项目在IISExpress调试中使用IP地址,便于开发调试
    基于SqlSugar的开发框架循序渐进介绍(17) 基于CSRedis实现缓存的处理
  • 原文地址:https://www.cnblogs.com/yufang/p/5262001.html
Copyright © 2020-2023  润新知