zoukankan      html  css  js  c++  java
  • block的哪些事 --- 学习笔记十

      //带有自动变量值的匿名函数

        //block 与 C语言函数比只有两点不同,1.没有函数名。 2.带有“^”。

        //类似于方法,如B中的值传给A中,在B中,一. 定义 ; 二. 实现。  在A中. 一. 调用。

     一、Block是什么?

       - 匿名函数

       - 截获自动变量

     二、Block语法。

    ---1.语法

    1.   ^  参数列表 表达式

    2.   ^ 参数列表 表达式

    3.   ^ 表达式

    4. 完整block详细图。

    1. (返回类型)(^block名称)(参数类型)=^(参数列表){代码实现};

    --- 自动变量的截获取

    int a = 256;
    const NSString *loves  = @"val ================> %d
    ";
     void (^STR)(void) = ^{
            NSLog(loves,a);
     }; //调用
    a = 100;
    loves = @"------------------I love You-----------------";
     STR(); //实现

    ---2. __block 说明符

            1.block对外部变量是只读的,要变成可读可写,就需要加上__block

            2.将栈中的block复制到堆上一份,从而避免了循环引用这个情况

            3.没有用__block 之前,自动变量的截获只能保存执行block语法瞬间的值。

            4.block 转c++ clang -rewrite-objc 源代码文件名。

            5. __block 可以指定任何类型的自动变量。

            6.对于用__block修饰的外部变量引用,block是复制其引用地址来实现访问的。

     注意:如果是全局变量的话,可以直接赋值,不用加__block ;

     NSInteger i = 0;
        void (^blk)() = ^{
           //Variable is not assignable (missing __block type specifier),编译器报错,变量未加__block,不能给自动变量(外部变量/局部变量)赋值.
          // i = 2;
        };

         可以在block内给自动变量赋值(外部变量/局部变量)。

     --- 实现//改成这样

    __block NSInteger let = 0;
    //调用
    void (^labels)() = ^{
        //Variable is not assignable (missing __block type specifier),编译器报错,变量未加__block,不能给自动变量(外部变量/局部变量)赋值.
          let = 2;
        NSLog(@"let====》%ld",let);
    };
    //实现
    labels();

    ---3. __weak 说明符

    //这个例子就造成了循环引用,(1)self(强引用)block. (2) 在block中又调用self的方法,block(强引用)self.   这样的话就造成循环引用

    //self 对block引用
    self.block = ^{ 
    
           [self layouts];   // 在block中又调用self的方法,这样就造成了循环引用。
    }

      三、Block的用途及注意事项。

        - 作为函数参数

        - 反向传值

        - 循环引用

        - Block的使用注意

    • block内部可以访问外部的变量,block默认是将其复制到其数据结构中来实现访问的。
    • 默认情况下,block内部不能修改外面的局部变量,因为通过block进行闭包的变量是const的。
    • 给局部变量加上__block关键字,这个局部变量就可以在block内部修改,block是复制其引用地址来实现访问的。

        - Block作为属性应该用copy修饰

    1. 当用weak、assign修饰block属性时,block访问外部变量,此时block的类型是栈block。保存在栈中的block,当block所在函数方法返回结束,该block就会被销毁。在其他方法内部调用访问该block,就会引发野指针错误EXC_BAD_ACCESS
    2. 当用copy、strong修饰block属性时,block访问外部变量,此时block的类型是堆block。保存在堆中的block,当引用计数器为0时被销毁,该类型block是由栈类型的block从栈中复制到堆中形成的,因此可以在其他方法内部调用该block。在ARC下,strongcopy都可以用来修饰block,但是建议修饰block属性使用copy

    四.所有栗子:

    //(1)定义无参无返回值的Block
    
        void (^noneBack)() = ^(){
          
            NSLog(@"定义无参数无返回值的block");
        };
        noneBack();
    //(2)定义有参数无返回值的Block
        void (^oneBack)(NSString *str) = ^(NSString *strs){
            
            NSLog(@"%@",strs);
        };
        oneBack(@"我是一个参数的block");
    //(3)定义有参数int返回值的Block
        int (^intBack)(int ,int) = ^(int a,int b){
            
            return a+b;
        };
        int sum = intBack(100,200);
        NSLog(@"a+b== %d",sum);

    五.block在其它语言的说法

      

    将来的自己,会感谢现在不放弃的自己!
  • 相关阅读:
    详细解析Windows按键突破专家的原理
    详细解析Windows按键突破专家的原理
    简单线程注入的实现
    运用 Evince 阅读 PDF 电子书
    Sonata 0.7
    P7ZIP-Linux 中的 7Zip
    Firefox 特征扩展:Video Download
    若何在嵌入式Linux及下建造QPF字库
    Wink-Flash 演示录制软件
    自由软件:理想与实践
  • 原文地址:https://www.cnblogs.com/TheYouth/p/6023698.html
Copyright © 2011-2022 走看看