美文网首页
每周学习总结(block使用)

每周学习总结(block使用)

作者: 我是世界微小的存在 | 来源:发表于2017-10-19 10:19 被阅读0次

    概述:

    代码块Block是苹果在iOS4开始引入的对C语言的扩展,用来实现匿名函数的特性,Block是一种特殊的数据类型,其可以正常定义变量、作为参数、作为返回值,特殊地,Block还可以保存一段代码,在需要的时候调用,目前Block已经广泛应用于iOS开发中,常用于GCD、动画、排序及各类回调

    注: Block的声明与赋值只是保存了一段代码段,必须调用才能执行内部代码

    Block变量的声明、赋值与调用

    Block变量的声明
    Block变量的声明格式为: 返回值类型(^Block名字)(参数列表);
    
    // 声明一个无返回值,参数为两个字符串对象,叫做aBlock的Block
    void(^aBlock)(NSString *x, NSString *y);
    
    // 形参变量名称可以省略,只留有变量类型即可
    void(^aBlock)(NSString *, NSString *);
    
    
    Block变量的赋值
    Block变量的赋值格式为: Block变量 = ^(参数列表){函数体};
    
    aBlock = ^(NSString *x, NSString *y){
        NSLog(@"%@ love %@", x, y);
    };
    

    注: Block变量的赋值格式可以是: Block变量 = ^返回值类型(参数列表){函数体};,不过通常情况下都将返回值类型省略,因为编译器可以从存储代码块的变量中确定返回值的类型

    声明Block变量的同时进行赋值
    int(^myBlock)(int) = ^(int num){
        return num * 7;
    };
    
    // 如果没有参数列表,在赋值时参数列表可以省略
    void(^aVoidBlock)() = ^{
        NSLog(@"I am a aVoidBlock");
    };
    
    Block变量的调用
    // 调用后控制台输出"Li Lei love Han Meimei"
    aBlock(@"Li Lei",@"Han Meimei");
    
    // 调用后控制台输出"result = 63"
    NSLog(@"result = %d", myBlock(9));
    
    // 调用后控制台输出"I am a aVoidBlock"
    aVoidBlock();
    

    使用typedef定义Block类型

    在实际使用Block的过程中,我们可能需要重复地声明多个相同返回值相同参数列表的Block变量,如果总是重复地编写一长串代码来声明变量会非常繁琐,所以我们可以使用typedef来定义Block类型

    // 定义一种无返回值无参数列表的Block类型
    typedef void(^SayHello)();
    
    // 我们可以像OC中声明变量一样使用Block类型SayHello来声明变量
    SayHello hello = ^(){
        NSLog(@"hello");
    };
    
    // 调用后控制台输出"hello"
    hello();
    

    Block作为函数参数

    Block作为C函数参数
    // 1.定义一个形参为Block的C函数
    void useBlockForC(int(^aBlock)(int, int))
    {
        NSLog(@"result = %d", aBlock(300,200));
    }
    
    // 2.声明并赋值定义一个Block变量
    int(^addBlock)(int, int) = ^(int x, int y){
        return x+y;
    };
    
    // 3.以Block作为函数参数,把Block像对象一样传递
    useBlockForC(addBlock);
    
    // 将第2点和第3点合并一起,以内联定义的Block作为函数参数
    useBlockForC(^(int x, int y) {
        return x+y;
    });
    
    Block作为OC函数参数
    // 1.定义一个形参为Block的OC函数
    - (void)useBlockForOC:(int(^)(int, int))aBlock
    {
        NSLog(@"result = %d", aBlock(300,200));
    }
    
    // 2.声明并赋值定义一个Block变量
    int(^addBlock)(int, int) = ^(int x, int y){
        return x+y;
    };
    
    // 3.以Block作为函数参数,把Block像对象一样传递
    [self useBlockForOC:addBlock];
    
    // 将第2点和第3点合并一起,以内联定义的Block作为函数参数
    [self useBlockForOC:^(int x, int y){
        return x+y;
    }];
    
    
    使用typedef简化Block
    // 1.使用typedef定义Block类型
    typedef int(^MyBlock)(int, int);
    
    // 2.定义一个形参为Block的OC函数
    - (void)useBlockForOC:(MyBlock)aBlock
    {
        NSLog(@"result = %d", aBlock(300,200));
    }
    
    // 3.声明并赋值定义一个Block变量
    MyBlock addBlock = ^(int x, int y){
        return x+y;
    };
    
    // 4.以Block作为函数参数,把Block像对象一样传递
    [self useBlockForOC:addBlock];
    
    // 将第3点和第4点合并一起,以内联定义的Block作为函数参数
    [self useBlockForOC:^(int x, int y){
        return x+y;
    }]
    
    

    Block内访问局部变量

    在Block中可以访问局部变量

    // 声明局部变量global
    int global = 100;
    
    void(^myBlock)() = ^{
        NSLog(@"global = %d", global);
    };
    // 调用后控制台输出"global = 100"
    myBlock();
    
    在声明Block之后、调用Block之前对局部变量进行修改,在调用Block时局部变量值是修改之前的旧值
    // 声明局部变量global
    int global = 100;
    
    void(^myBlock)() = ^{
        NSLog(@"global = %d", global);
    };
    global = 101;
    // 调用后控制台输出"global = 100"
    myBlock();
    
    在Block中不可以直接修改局部变量
    // 声明局部变量global
    int global = 100;
    
    void(^myBlock)() = ^{
        global ++; // 这句报错
        NSLog(@"global = %d", global);
    };
    // 调用后控制台输出"global = 100"
    myBlock();
    

    Block内访问__block修饰的局部变量

    在局部变量前使用下划线下划线block修饰,在声明Block之后、调用Block之前对局部变量进行修改,在调用Block时局部变量值是修改之后的新值
    // 声明局部变量global
    __block int global = 100;
    
    void(^myBlock)() = ^{
        NSLog(@"global = %d", global);
    };
    global = 101;
    // 调用后控制台输出"global = 101"
    myBlock();
    
    在局部变量前使用下划线下划线block修饰,在Block中可以直接修改局部变量
    // 声明局部变量global
    __block int global = 100;
    
    void(^myBlock)() = ^{
        global ++; // 这句正确
        NSLog(@"global = %d", global);
    };
    // 调用后控制台输出"global = 101"
    myBlock();
    

    Block内访问全局变量

    在Block中可以访问全局变量
    // 声明全局变量global
    int global = 100;
    
    void(^myBlock)() = ^{
        NSLog(@"global = %d", global);
    };
    // 调用后控制台输出"global = 100"
    myBlock();
    
    在声明Block之后、调用Block之前对全局变量进行修改,在调用Block时全局变量值是修改之后的新值
    // 声明全局变量global
    int global = 100;
    
    void(^myBlock)() = ^{
        NSLog(@"global = %d", global);
    };
    global = 101;
    // 调用后控制台输出"global = 101"
    myBlock();
    
    在Block中可以直接修改全局变量
    // 声明全局变量global
    int global = 100;
    
    void(^myBlock)() = ^{
        global ++;
        NSLog(@"global = %d", global);
    };
    // 调用后控制台输出"global = 101"
    myBlock();
    

    Block内访问静态变量

    在Block中可以访问静态变量
    // 声明静态变量global
    static int global = 100;
    
    void(^myBlock)() = ^{
        NSLog(@"global = %d", global);
    };
    // 调用后控制台输出"global = 100"
    myBlock();
    
    在声明Block之后、调用Block之前对静态变量进行修改,在调用Block时静态变量值是修改之后的新值
    // 声明静态变量global
    static int global = 100;
    
    void(^myBlock)() = ^{
        NSLog(@"global = %d", global);
    };
    global = 101;
    // 调用后控制台输出"global = 101"
    myBlock();
    
    在Block中可以直接修改静态变量
    // 声明静态变量global
    static int global = 100;
    
    void(^myBlock)() = ^{
        global ++;
        NSLog(@"global = %d", global);
    };
    // 调用后控制台输出"global = 101"
    myBlock();
    
     http://www.jianshu.com/p/14efa33b3562
    

    相关文章

      网友评论

          本文标题:每周学习总结(block使用)

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