OC Block

301 阅读2分钟
  • Block是iOS中一种比较特殊的数据类型

  • Block的作用

    • 用来保存某一段代码, 可以在恰当的时间再取出来调用
    • 功能类似于函数和方法

格式

返回值类型 (^block变量名)(形参列表) = ^(形参列表) {

};
  • 没有返回值,也没有形参
void (^roseBlock) ();
    // 如果block没有参数, 那么^后面的()可以省略
    //roseBlock =
    //等号右边就是block要赋的值
    roseBlock = ^(){
        printf("  {@} \n");
        printf("   |  \n");
        printf("  \\|/ \n");
        printf("   | \n");
    };
    // 要想执行block保存的代码, 必须调用block才会执行
roseBlock();
  • 没有返回值,有形参
void (^roseBlock) (int);
    roseBlock = ^(int num){
        for (int i = 0; i < num; ++i) {
            printf("  {@} \n");
            printf("   |  \n");
            printf("  \\|/ \n");
            printf("   | \n");
        }
    }; 
roseBlock(2);
  • 有返回值,有形参
int (^sumBlock) (int, int);
    sumBlock =^(int value1, int value2){
        return value1 + value2;
    };
    NSLog(@"sum = %i", sumBlock(10, 40));

block和typedef

// 注意: 利用typedef给block起别名, 和指向函数的指针一样, block变量的名称就是别名
typedef int (^calculteBlock)(int , int);

calculteBlock sumBlock = ^(int value1, int value2){
        return value1 + value2;
    };
    NSLog(@"sum = %i", sumBlock(20, 10));

block用做参数

void goToWork(void (^workBlock)())
{
    NSLog(@"起床");
    NSLog(@"穿衣服");
    NSLog(@"洗漱");
    NSLog(@"喝早茶");
    NSLog(@"驾车去上班");
   
    // 不一样
    // 调用传递的block参数
    workBlock();
    
    NSLog(@"收拾东西");
    NSLog(@"驾车回家");
    NSLog(@"吃晚饭");
    NSLog(@"洗澡");
    NSLog(@"睡觉");
}

void goToWorkInDay1()
{
//调用goToWork函数,传递block参数值
    goToWork(^{
        NSLog(@"认识新同事");
    });
}

int main(int argc, const char * argv[]) {
    goToWorkInDay1();
    return 0;
}

Block注意事项

  • 没有访问外部变量是全局block,存储代码区

    访问外部变量,block copy,存储堆区

  • 在block内部可以访问block外部的变量

  • block内部也可以定义和block外部的同名的变量(局部变量),此时局部变量会暂时屏蔽外部

    • 默认情况下, Block内部不能修改外面的局部变量

      Block内部可以修改使用__block修饰的局部变量

    如果block中访问到了外界的变量, block会将外界的变量拷贝一份到堆内存中,block中的变量和外界的变量并不是同一个变量。因为block中使用的外界变量是copy的, 所以在调用之前修改外界变量的值, 不会影响到block中copy的值

    • 如果没有添加__block是值传递

    • 如果加上__block之后就是地址传递,

    __block int b = 5;
    void (^myBlock)() = ^{
      b = 20;
      NSLog(@"b = %i", b);
      };
    myBlock();
    //输出结果: 20