美文网首页
iOS底层 -- Blcok本质之对象类型的auto变量

iOS底层 -- Blcok本质之对象类型的auto变量

作者: happy神悦 | 来源:发表于2020-09-10 09:37 被阅读0次

1.如果block是在栈上,将不会对auto变量产生强引用

MRC环境
int main(int argc, char * argv[]) {
    @autoreleasepool {
        Block block;
        {
            Person *person = [[Person alloc] init];
            person.age = 10;
            block = ^{
                NSLog(@"%d", person.age);
            };
            [person release];
        }
    }
    return 0;
}
struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  Person *person; // 不会产生强引用
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, Person *_person, int flags=0) : person(_person) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};

2.如果block被拷贝到堆上

  • 会调用block内部的copy函数
  • copy函数内部会调用_Block_object_assign函数
  • _Block_object_assign函数会根据auto变量的修饰符(__strong,_weak)做出相应的操作,形成强引用,弱引用。
MRC环境
int main(int argc, char * argv[]) {
    @autoreleasepool {
        Block block;
        {
            Person *person = [[Person alloc] init];
            person.age = 10;
            block = [^{
                NSLog(@"%d", person.age);
            } copy];  // 进行copy操作
            [person release];
        }
    }
    return 0;
}
struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  Person *person; // 产生强引用
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, Person *_person, int flags=0) : person(_person) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};
ARC环境
int main(int argc, char * argv[]) {
    @autoreleasepool {
        
        Block block;
        {
            Person *person = [[Person alloc] init];
            person.age = 10;
            __weak Person *weakPerson = person;
            block = ^{
                NSLog(@"%d", weakPerson.age);
            };
        }
    }
    return 0;
}
struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  // 根据auto变量的修饰符(__strong,_weak)做出相应的操作,形成强引用,弱引用
  Person *__weak weakPerson; 
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, Person *_person, int flags=0) : person(_person) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};

3.如果block从堆上移除

  • 会调用block内部的dispose函数
  • dispose函数内部会调用_Block_object_dispose函数
  • _Block_object_dispose函数会自动释放引用的auto变量,类似于release。

相关文章

网友评论

      本文标题:iOS底层 -- Blcok本质之对象类型的auto变量

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