从声明定义到底层原理,搞懂block的全部内容系列文章(四)__block的底层实现

四 __block的底层实现
前言

本文是block系列的最后一篇,我们知道block有个特性,在block代码体内部不能修改所捕获的外部非静态局部变量的值(全局变量和静态局部变量的值可以修改),如果想修改,需要在变量前面加上__block,本文主要讲述__block的作用和实现原理。

block的底层实现

先看代码:

int main(int argc, const char * argv[]) {
    __block int d = 100;
    __block Person *person = [[Person alloc]init];
    void (^block2)(void) = ^{
        d = 200;
        person = nil;
    };
    return 0;
}
int main(int argc, const char * argv[]) {
    __Block_byref_d_0 d = {
    (void*)0,
    (__Block_byref_d_0 *)&d,
     0,
     sizeof(__Block_byref_d_0),
     100};
	__Block_byref_person_1 person = {
	(void*)0,
	person, 
	33554432, 
	sizeof(__Block_byref_person_1), 
	__Block_byref_id_object_copy_131, 
	__Block_byref_id_object_dispose_131, 
	[[Person alloc]init]};
	
    block2 = __main_block_impl_0(
    __main_block_func_0, 
    __main_block_desc_0, 
    d, 
    person);
    return 0;
}
struct __Block_byref_d_0 {
  void *__isa;
__Block_byref_d_0 *__forwarding;
 int __flags;
 int __size;
 int d;
};
struct __Block_byref_person_1 {
  void *__isa;
__Block_byref_person_1 *__forwarding;
 int __flags;
 int __size;
 void (*__Block_byref_id_object_copy)(void*, void*);
 void (*__Block_byref_id_object_dispose)(void*);
 Person *__strong person;
};

通过观察代码,我们知道,甭管是int类型还是Person类型,添加上__block后,这些自动变量都被包装成了struct _Block_byref**,而这个结构内部,有isa指针,且采用值复制的方式复制了int和person指针的值,基本类型和引用类型的区别在于,引用类型的结构体中多了两个函数指针copy和dispose,这两个指针是用来管理person的引用计数的。所以__block添加后,局部变量被包裹了一层,变成了OC对象,其内存引用关系图如下所示:__block对象的引用计数关系图
至此,block的内容介绍完毕,如发现疏漏,欢迎沟通交流。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值