栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

OC:关于block的本质,你懂了吗?

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

OC:关于block的本质,你懂了吗?

✅作者简介:大家好我是瓜子三百克,一个非科班出身的技术程序员,还是喜欢在学习和开发中记录笔记的博主小白!
个人主页:瓜子三百克的主页
如果觉得博主的文章还不错的话,请点赞+收藏⭐️+留言支持一下博主哦爛


本节带你分析 block 的底层实现(block本质)。废话不多说,先来一张下饭的底层结构图:

1、实现一个简单的block

下面我们来一步步分析block的实现原理,以下面一段代码为例,来查看OC的底层实现:

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        void(^block)(void) = ^{
            NSLog(@"Hello, World!");
        };
        block();
    }
    return 0;
}
2、代码转成C++

打开命令行,cd 到 main.m 的目录下,执行以下命令:

xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m

执行玩命令后,在同目录下会生成 main.cpp 文件,然后将文件导入项目(注意:该文件不参与编译)。

3、底层代码分析

内部每一行代码都配置了详细的说明:

// 1、程序入口
int main(int argc, const char * argv[]) {
     { __AtAutoreleasePool __autoreleasepool; 

        
        void(*block)(void) = &__main_block_impl_0(
        	__main_block_func_0, // 4、函数执行逻辑的代码
        &__main_block_desc_0_DATA);
        
        // void(*block)(void) = &结构体
        // 因此 block 的本质是一个指向结构体的对象
        
        // 执行block内部代码
        block->FuncPtr(block);
    }
    return 0;
}


// 2.1、调用该函数,返回的是一个结构体对象
struct __main_block_impl_0 {
  struct __block_impl impl;// 2.1a、block结构体:主要参数信息
  struct __main_block_desc_0* Desc;// 2.1b、block结构体:关于block信息的描述(记录内存大小)
   
   // 2.1c、cpp的构造函数(类似OC的init方法,原来什么类型,返回什么对象类型)赋值:返回结构体对象
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int flags=0) {
  	// 给变量赋值
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};

// 2.1a、block结构体:主要参数信息
struct __block_impl {
  void *isa;// 因为结构体中有 isa 指针,那么可以知道 klock 是一个OC对象
  int Flags;//标记,默认为0
  int Reserved;// 预留参数
  void *FuncPtr;// 指向要执行的函数地址指针
};

// 2.1b、block结构体:关于block信息的描述(记录内存大小)
static struct __main_block_desc_0 {
  size_t reserved;// 预留参数
  size_t Block_size;// 记录block占据的内存大小
} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0)};



// 3.1、封装了 block 执行逻辑的函数
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
            NSLog((NSString *)&__NSConstantStringImpl__var_folders_vc_pn677_yj1sz8hgf_q5bjvssc0000gn_T_main_c7471a_mi_0);
}

// 3.2、关于block描述结构体的肤质
static struct __main_block_desc_0 {
  size_t reserved;// 预留参数 0
  size_t Block_size;// 计算block大小后的值
} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0)};


提问:block的原理是怎样的?(本质是什么?)

block是封装了函数调用以及调用环境的OC对象。



**结束语 **

最后如果觉得我写的文章对您有帮助的话,欢迎点赞✌,收藏✌,加关注✌哦,谢谢谢谢!!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/862324.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号