美文网首页
Block-对象类型的auto变量

Block-对象类型的auto变量

作者: 越天高 | 来源:发表于2020-10-27 09:24 被阅读0次

    01

    typedef void(^MyBlock)(void);
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool
        {
            MyBlock block;
            
            {
                Person *p = [Person new];
               block = ^{
                    NSLog(@"%@", p);
    
                };
            }
            
        }
        return 0;
    }
    
    

    ARC中对象变量在执行完作用域之后并没有被销毁,因为他会有一个强指针指向了原来那个对象,
    如果我们访问使用下面的方式

                __weak Person *weakP = p;
    

    就不会对外面的变量产生强引用,所以就不会影响他的生命周期

    02

    当block内部访问了对象类型的auto变量时
    如果block是在栈上,将不会对auto变量产生强引用
    如果block被拷贝到堆上
    会调用block内部的copy函数
    copy函数内部会调用_Block_object_assign函数
    _Block_object_assign函数会根据auto变量的修饰符(__strong、__weak、__unsafe_unretained)做出相应的操作,形成强引用(retain)或者弱引用
    如果block从堆上移除
    会调用block内部的dispose函数
    dispose函数内部会调用_Block_object_dispose函数
    _Block_object_dispose函数会自动释放引用的auto变量,断开对对象的引用(类似release)

    03

    当我们block访问的变量为简单的数据类型的时候,他的内部结构组成为下图,只有两个成员,

    
            MyBlock block;
            {
                Person *p = [Person new];
                int age = 10;
                block = ^{
                    NSLog(@"%@", age);
                };
            }
            
    static struct __main_block_desc_0 {
      size_t reserved;
      size_t Block_size;
    }
    
    

    但是如果他访问的auto变量为对象类型的时候,这个结构体里面就多了两个成员,对内部要访问的对象做内存管理。

    static struct __main_block_desc_0 {
      size_t reserved;
      size_t Block_size;
      void (*copy)(struct __main_block_impl_0*, struct __main_block_impl_0*);
      void (*dispose)(struct __main_block_impl_0*);
    }
    

    新建一个iOS项目来演示延时操作

    Person *person = [Person new];
            __weak Person *weakP = person;
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    NSLog(@"%@",person)
                });
                NSLog(@"%@", weakP);
                
            });
    

    block什么释放对象,要看用强指针引用的block什么时候执行完毕

    相关文章

      网友评论

          本文标题:Block-对象类型的auto变量

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