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

2020-09-10  本文已影响0人  happy神悦

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被拷贝到堆上

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从堆上移除

上一篇 下一篇

猜你喜欢

热点阅读