美文网首页
5-1 Block变量截获

5-1 Block变量截获

作者: Rumbles | 来源:发表于2019-04-10 22:10 被阅读0次

    __block:解决block循环引用

    1.__weak
    2.__block。 记住置为nil
    3.block作为参数
    self.block = ^(view controller *vc) {
    nslog (self.name)
    }。///> 保存函数代码块

    self.block(self); ///> 执行方法

    4.为什么有问题 0x7 栈区
    5.block是一个结构体对象
    6.自动捕获变量 a

    1.面试题. 截获变量

        int multiplier = 6;
        int (^Block)(int) = ^int(int num) {
            return num * multiplier;
        };
        multiplier = 4;
        NSLog(@"result is %d",Block(2));   12
    
    局部变量 -->. 基本数据变量。对象类型 
    
    静态局部变量
    
    全局变量
    
    静态全局变量
    
    block截获的 使用前的数据
    
    对于基本数据类型 的局部变量 截获其值
    对于 对象类型的局部变量 连同所有权修饰符一起截获
    
        static  int multiplier = 6;
        int (^Block)(int) = ^int(int num) {
            return num * multiplier;
        };
        multiplier = 4;
        NSLog(@"result is %d",Block(2));  8
    

    2.__block

     __block. 指针传递。   可以修改值  
    没有   __block。值传递
    
    
    对 截获变量进行赋值操作时需要 使用。 __block
    
        NSMutableArray *array = [NSMutableArray array];
        NSMutableArray *array1 = [NSMutableArray array];
        [array addObject:@"1"];
        void(^block)(void) = ^ {
            NSLog(@"array:%@  array1:%@",array,array1);
        };
        [array addObject:@"2"];
        array1 = @[@"2234234234",@"2342342"].mutableCopy;
        block();
    
    内部保存的是array之前的指针  array1 之后的指针发生了变化
    /*
    array:(
        1,
        2
    )  array1:(
    )
    */  
    
    没有赋值 不要使用__block
    
    
    对静态变量。全局变量 静态全局变量。不需要使用__block
    
    
        __block  int multiplier = 6;  指针
        int (^Block)(int) = ^int(int num) {
            return num * multiplier;
        };
        multiplier = 4;
        NSLog(@"result is %d",Block(2));  8
    

    3.Block的内存管理

    Block_copy()必须与相应的Block_release() MRC下才可以使用
    
    
    ARC下直接使用copy
        NSInteger interI = 10;
        NSInteger i = 10;
        block = [^{
            NSLog(@"%ld", interI);
        } copy];
    

    4.Block的原理是什么?本质是什么

    Block 本身也有一个isa指针 说明Block也是一个OC对象
    封装了代码块。合适的时候执行
    
    本身保存了 函数执行的地址。还有我们需要的参数
    
    为什么局部变量需要捕获参数 到 block里面
    因为是跨函数访问。 到另外一个函数里面就访问不到了。但是全局的事可以访问的
    
    局部变量: auto。值访问。 会销毁
                       static。指针访问
    

    5.Block的类

        NSLog(@"%@",[block class]);
        NSLog(@"%@",[[block class] superclass] );
        NSLog(@"%@",[[[block class] superclass] superclass]);
        NSLog(@"%@",[[[[block class] superclass] superclass] superclass]);
    
    2019-06-24 22:23:56.751697+0800 OC-Test[96730:11558820] __NSMallocBlock
    2019-06-24 22:23:56.751733+0800 OC-Test[96730:11558820] NSBlock
    2019-06-24 22:23:56.751780+0800 OC-Test[96730:11558820] NSObject
    
    
            // 堆:动态分配内存,需要程序员申请申请,也需要程序员自己管理内存
            void (^block1)(void) = ^{
                NSLog(@"Hello");
            };
            
            int age = 10;
            void (^block2)(void) = ^{
                NSLog(@"Hello - %d", age);
            };
            
            NSLog(@"%@ %@ %@", [block1 class], [block2 class], [^{
                NSLog(@"%d", age);
            } class]);
    __NSGlobalBlock__ 放在数据段里面
    __NSMallocBlock__ 堆区
    __NSStackBlock__ 栈区
    
    没有访问auto变量的block是__NSGlobalBlock __ ,放在数据段
    访问了auto变量的block是__NSStackBlock __
    [__NSStackBlock __ copy]操作就变成了__NSMallocBlock __
    
    
    在ARC环境下,编译器会根据情况自动将栈上的block复制到堆上的几种情况?
    
    1.block作为函数返回值时 【使用了auto变量的时候】
    2.将block赋值给__strong指针时
    3.block作为Cocoa API中方法名含有usingBlock的方法参数时
    4.block作为GCD API的方法参数时
    
    栈空间的block是不会强引用 外面的 auto对象的
    堆空间的block如果 如果是强引用那么里面也会强引用
    

    Block内存管理实例分析
    Block的本质

    相关文章

      网友评论

          本文标题:5-1 Block变量截获

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