美文网首页
block大全

block大全

作者: Mr_董 | 来源:发表于2017-04-10 23:03 被阅读26次
  • Block类型是一个C级别的语法和运行机制。


    block图.png

    实例:

//定义有返回值和参数的block
int (^sumBlock2)(int x, int y) = ^ int (int a, int b) {
        return a + b;
 };
//调用有返回值的block 
NSLog(@"%d", sumBlock2(4, 8));
  • typedef使用
//给无参无返回值block变量起别名; 
//格式: void (^新类型名)(); 
typedef void (^newType)();
//用新的类型定义block变量 newType t1;
t1 = ^{ 
      NSLog(@"我是使用newType定义出来的变量t1的值");
};
//调用block 
t1();

有参数有返回值的block起别名

//给有参数有返回值的block起别名
        typedef int(^blockType2)(int ,int );
        blockType2 b2 = ^(int x,int y){
            return x>y?x:y;
        };
        //max保存的是代码块执行的结果
        int max = b2(119,45);
  • 函数指针
 //调用函数
        int s =  sum(10, 119);  //函数名存放的是函数的首地址
        //定义函数指针
        int (*p)(int a,int b);  //p 函数指针变量
        typedef int (*p1)(int a,int b);   //给返回值是int 并且有两个参数的函数指针起一个别名  别名是p1 (是一个类型)
        p = sum;
        p1 = a
        s = (*p)(10,119);
        NSLog(@"s = %d",s);
访问外部变量
  1. 注意在block代码块的内部使用外部变量的时候注意
    1)在block定义的时候,把block外部的变量的值copy到了内存的堆区
    2)拷贝的过程中使用了const(以const的形式把外部变量做了一个copy)--要想修改值使用__block
  2. 注意:一旦把使用__block修饰某个变量,注意block之后,使用的都是 堆区的变量
  3. __block 修饰符 告诉编译器,i的值可以在block内部修改(忽略检查)
block作为函数参数
//通过函数,传递一个参数,
void test(void (^myblock)()){
    if (myblock) {
        //调用block
        myblock();
    }
}
//两种方式实现
//定义一个代码块,打印
        void (^b1)()=^{
            NSLog(@"**********");
            NSLog(@"**********");
            NSLog(@"哈哈哈");
        };
        //调用
        test(b1);
        test(^{
            NSLog(@"wwwwwwww");
        });

block作为方法的返回值
//声明
typedef void(^blockType)();
-(blockType)test2;
//实现
-(blockType)test2{
    return ^{
        NSLog(@"test2 return block");
    };
}
//调用
//返回值是block类型的方法
       blockType b1  = [p test2];
       b1();

三种类型的block

根据Block在内存中的位置分为三种类型NSGlobalBlock,NSStackBlock, NSMallocBlock。 NSGlobalBlock:类似函数,位于代码段; NSStackBlock:位于栈内存,函数返回后Block将无效; NSMallocBlock:位于堆内存。

  • 全局block (NSGlobalBlock),定义在函数外面的block是global的。
    如果函数内部的 block,但是没有捕获任何自动变量,那么它也是全局的(ARC和MRC都一样)。
  • 栈block
  • 堆block 则是对栈block copy 得来。对全局block copy 不会有任何作用,返回的依然是全局block。

block类型变量内存管理参数为什么要使用 copy

1.不管在MRC还是在ARC,使用assign 修饰的block,都是栈block,栈block会被提前释放。
2.在ARC下 block类型的变量 strong 相当于 copy。但是我们不会直接写成strong 而是写成 copy

block的内存隐患

Block_copy(bb);   //copy block到堆区(bb位于堆区了)
Block_release(bb);  //释放b1的空间(b1已经是一个堆block)

相关文章

网友评论

      本文标题:block大全

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