block循环引用

typedef void(^GHBlock)(void);

原生图片

底层源码

typedef void(*GHBlock)(void);

struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  GHPerson *person;
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, GHPerson *_person, int flags=0) : person(_person) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
  GHPerson *person = __cself->person; // bound by copy


            NSLog((NSString *)&__NSConstantStringImpl__var_folders_5r_8b0nqlv12v5ftv77b9t0v04h0000gn_T_main_5b5b91_mi_0,((int (*)(id, SEL))(void *)objc_msgSend)((id)person, sel_registerName("age")));

        }
static void __main_block_copy_0(struct __main_block_impl_0*dst, struct __main_block_impl_0*src) {_Block_object_assign((void*)&dst->person, (void*)src->person, 3/*BLOCK_FIELD_IS_OBJECT*/);}

static void __main_block_dispose_0(struct __main_block_impl_0*src) {_Block_object_dispose((void*)src->person, 3/*BLOCK_FIELD_IS_OBJECT*/);}

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*);
} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0), __main_block_copy_0, __main_block_dispose_0};
int main(int argc, const char * argv[]) {
    /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 


        GHPerson *person = ((GHPerson *(*)(id, SEL))(void *)objc_msgSend)((id)((GHPerson *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("GHPerson"), sel_registerName("alloc")), sel_registerName("init"));
        
        ((void (*)(id, SEL, int))(void *)objc_msgSend)((id)person, sel_registerName("setAge:"), 10);
        
        ((void (*)(id, SEL, GHBlock _Nonnull))(void *)objc_msgSend)((id)person, sel_registerName("setBlock:"), ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, person, 570425344)));

        NSLog((NSString *)&__NSConstantStringImpl__var_folders_5r_8b0nqlv12v5ftv77b9t0v04h0000gn_T_main_5b5b91_mi_1);
    }
    return 0;
}

block强引用person

block强引用person

person强引用block
person强引用block

block循环引用解决方案:
__weak:使用弱引用解除循环引用,不会产生强引用,指向的对象销毁时,会自动让指针置为nil。
__block:此种解决方案必须要调用block
__unsafe_unretained:不会产生强引用,不安全,指向的对象销毁时,指针存储的地址值不变。
__unsafe_unretained typeof(person) weakPerson = person;

源码

   GHPerson *person = [[GHPerson alloc]init];
        person.age = 10;
//        [person test];
        
        
//        __unsafe_unretained:不会产生强引用
        __unsafe_unretained typeof(person) weakPerson = person;
        
        
        person.block = ^{

            NSLog(@"age is %d",weakPerson.age);

        };
//
        NSLog(@"1111111112");

转换后的底层源码
我们可以看到,typeof (person) weakPerson;这里只是一个类型判别,并不是向上面的GHPerson *person;一样。

typedef void(*GHBlock)(void);

struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  typeof (person) weakPerson;
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, typeof (person) _weakPerson, int flags=0) : weakPerson(_weakPerson) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
  typeof (person) weakPerson = __cself->weakPerson; // bound by copy


            NSLog((NSString *)&__NSConstantStringImpl__var_folders_5r_8b0nqlv12v5ftv77b9t0v04h0000gn_T_main_4419cf_mi_0,((int (*)(id, SEL))(void *)objc_msgSend)((id)weakPerson, sel_registerName("age")));

        }
static void __main_block_copy_0(struct __main_block_impl_0*dst, struct __main_block_impl_0*src) {_Block_object_assign((void*)&dst->weakPerson, (void*)src->weakPerson, 3/*BLOCK_FIELD_IS_OBJECT*/);}

static void __main_block_dispose_0(struct __main_block_impl_0*src) {_Block_object_dispose((void*)src->weakPerson, 3/*BLOCK_FIELD_IS_OBJECT*/);}

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*);
} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0), __main_block_copy_0, __main_block_dispose_0};
int main(int argc, const char * argv[]) {
    /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 


        GHPerson *person = ((GHPerson *(*)(id, SEL))(void *)objc_msgSend)((id)((GHPerson *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("GHPerson"), sel_registerName("alloc")), sel_registerName("init"));
        ((void (*)(id, SEL, int))(void *)objc_msgSend)((id)person, sel_registerName("setAge:"), 10);




        __attribute__((objc_ownership(none))) typeof(person) weakPerson = person;


        ((void (*)(id, SEL, GHBlock _Nonnull))(void *)objc_msgSend)((id)person, sel_registerName("setBlock:"), ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, weakPerson, 570425344)));

        NSLog((NSString *)&__NSConstantStringImpl__var_folders_5r_8b0nqlv12v5ftv77b9t0v04h0000gn_T_main_4419cf_mi_1);
    }
    return 0;
}

__block:通过调用block来解决循环方案

源码

__block GHPerson *person = [[GHPerson alloc]init];
        person.age = 10;
        
        person.block = ^{

            NSLog(@"age is %d",person.age);
            person = nil;

        };
        person.block();

转换后的cpp底层代码

typedef void(*GHBlock)(void);
struct __Block_byref_person_0 {
  void *__isa;
__Block_byref_person_0 *__forwarding;
 int __flags;
 int __size;
 void (*__Block_byref_id_object_copy)(void*, void*);
 void (*__Block_byref_id_object_dispose)(void*);
 GHPerson *person;
};

struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  __Block_byref_person_0 *person; // by ref
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, __Block_byref_person_0 *_person, int flags=0) : person(_person->__forwarding) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
  __Block_byref_person_0 *person = __cself->person; // bound by ref


            NSLog((NSString *)&__NSConstantStringImpl__var_folders_5r_8b0nqlv12v5ftv77b9t0v04h0000gn_T_main_94729c_mi_0,((int (*)(id, SEL))(void *)objc_msgSend)((id)(person->__forwarding->person), sel_registerName("age")));
            (person->__forwarding->person) = __null;

        }
static void __main_block_copy_0(struct __main_block_impl_0*dst, struct __main_block_impl_0*src) {_Block_object_assign((void*)&dst->person, (void*)src->person, 8/*BLOCK_FIELD_IS_BYREF*/);}

static void __main_block_dispose_0(struct __main_block_impl_0*src) {_Block_object_dispose((void*)src->person, 8/*BLOCK_FIELD_IS_BYREF*/);}

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*);
} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0), __main_block_copy_0, __main_block_dispose_0};
int main(int argc, const char * argv[]) {
    /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 
        __attribute__((__blocks__(byref))) __Block_byref_person_0 person = {(void*)0,(__Block_byref_person_0 *)&person, 33554432, sizeof(__Block_byref_person_0), __Block_byref_id_object_copy_131, __Block_byref_id_object_dispose_131, ((GHPerson *(*)(id, SEL))(void *)objc_msgSend)((id)((GHPerson *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("GHPerson"), sel_registerName("alloc")), sel_registerName("init"))};
        ((void (*)(id, SEL, int))(void *)objc_msgSend)((id)(person.__forwarding->person), sel_registerName("setAge:"), 10);

        ((void (*)(id, SEL, GHBlock _Nonnull))(void *)objc_msgSend)((id)(person.__forwarding->person), sel_registerName("setBlock:"), ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, (__Block_byref_person_0 *)&person, 570425344)));
        ((GHBlock (*)(id, SEL))(void *)objc_msgSend)((id)(person.__forwarding->person), sel_registerName("block"))();
    }
    return 0;
}

需要注意的是:MRC环境下不支持若指针的解决方案,既不支持__weak,而且使用__block不会产生强引用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北方人深漂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值