美文网首页
Block 使用 理解

Block 使用 理解

作者: 红色海_ | 来源:发表于2019-11-20 23:59 被阅读0次

    一,基础认识


    block的声明

    很像函数指针,把 * 换成^ 。前面是返回类型,中间是块名,最后是参数类型。

    // returnType (^BlockName) (Parameters)
    int (^YourBlockName) (int, int);
    
    // 简化声明,  typedef登场
    typedef int(^FuncAdd)(int, int);
    FuncAdd add = ^int(int a, int b) {
            return a+b;
    };
    add(100, 200);
    
    block的实现
    // ^returnType(Parameters){/*Put your code abcdefg */};
    ^int(int a, int b) {
        return a+b;
    };
    

    返回值类型是可省略, 可自动判断,如果参数也是空,可简化成这样式儿的:

    ^( ) {
        ;
    };
    

    你可能会觉得,“这是啥啊!”。。

    block的使用

    根调用C函数一个样

    YourBlockName(100, 200)
    
    block特性

    捕获 声明所在范围的所有变量。

     int count = 0;
     count = 1;
     int (^block2)(void) = ^{
            return count;
     };
     count = 2;
     int value = block2();   // value = 1
    

    却不能在block中修改捕获到的这些变量,尝试修改编译器报错。
    [图片上传失败...(image-b9b6c3-1574265520804)]
    )

    __block 修饰de变量可在块中修改 值

     __block int count = 0;
     int (^MyBlock)(void) = ^{
        count = 5;
        return count ;
     };
        
     int value1 = count;     // 0
     int value2 = MyBlock(); // 5
     int value3 = count;     // 5
    

    捕获变量只是拷贝了一份变量的值,用 __block 修饰后拷贝的是变量的地址.

    循环引用de问题
    例如ClassA持有block,block 中又用到了self. 循环引用 内存泄漏了。。。

     __weak typeof(self) weakSelf = self;
    YourBlock = ^{
       __strong typeof(self) strongSelf = weakSelf;
       NSLog(@"%@",   strongSelf.********);
    };
    

    二,深入理解

    block 的本质是啥呢?

    /* Revised new layout. */
    struct Block_descriptor {
        unsigned long int reserved;
        unsigned long int size;
        void (*copy)(void *dst, void *src);
        void (*dispose)(void *);
    };
    
    struct Block_layout {
        void *isa;  // 是个对象
        int flags;
        int reserved; 
        void (*invoke)(void *, ...); // 函数指针
        struct Block_descriptor *descriptor;
        /* Imported variables. */
    };
    
    类型

    OC 中共有3种:
    全局块,不访问任何外部变量
    栈块,保存在栈中, 函数退出就被销毁,通过copy可复制到堆上。
    堆块,保存在堆中。

    MRC 的环境下运行下面的代码:

    void (^globalBlock)()  = ^{ NSLog(@"I am global block"); };
    NSLog(@"%@", globalBlock);
            
    NSString *string1 = @"I am stack block";
    void (^stackBlcok)() = ^{ NSLog(@"%@", string1); };
    NSLog(@"%@", stackBlcok);
        
    NSString *string2 = @"I am malloc block";
    void (^mallockBlock)() = [^{ NSLog(@"%@", string2); } copy];
    NSLog(@"%@", mallockBlock);
    
    <__NSGlobalBlock__: 0x1000053b0>
    <__NSStackBlock__: 0x8fff5fbcc540>
    <__NSMallocBlock__: 0x201503da0>
    

    相关文章

      网友评论

          本文标题:Block 使用 理解

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