美文网首页
OC基础-Block(1)

OC基础-Block(1)

作者: 我是卖报的小行家 | 来源:发表于2021-03-06 09:38 被阅读0次

OC基础- block
Block:本质:一个OC对象,一个封装了函数调用以及函数调用环境的OC对象

先定义一个简单的block,上代码

    Int age = 23;
        void (^newBlock)(int a, int b) = ^(int a,int b){
            NSLog(@"测试Block1 a = %d",age);
            NSLog(@"测试Block2 b = %d",b);
        };

将其转化成.cpp文件以便查看源码
xcrun -sdk iphones clang -arch arm64 -rewrite-objc main.m

我们得到刚才那一段代码的本质

    int age = 10;
    //定义block对象
        void (*newBlock)(int a, int b) = ((void (*)(int, int))&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, age));
    //执行block内部代码
        ((void (*)(__block_impl *, int, int))((__block_impl *)newBlock)->FuncPtr)((__block_impl *)newBlock, 10, 30);

经过筛选得出来
block组成部分

         struct __main_block_impl_0 {
           struct __block_impl impl;
           void *isa;
            int Flags;
            int Reserved;
            void *FuncPtr;
           struct __main_block_desc_0* Desc;
           int age; //=>访问外部的age  
           __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int _age, int flags=0) : age(_age) {
             impl.isa = &_NSConcreteStackBlock;
             impl.Flags = flags;
             impl.FuncPtr = fp;
             Desc = desc;
           }
         };
其中__block_impl结构如下所示
    struct __block_impl {
            void *isa;
            int Flags;
            int Reserved;
            void *FuncPtr;
            };

其中struct __main_block_desc_0 里面结构如下(描述信息)
    struct __main_block_desc0{
        size_t reserved;
            size_t Block_size;
    };

从main函数可以看出来定义block的时候是直接把age值传进去的。

综合,
1.为什么说block是一个OC对象,因为内部有isa指针
2.为什么说block一个封装了函数调用以及函数调用环境的OC对象
看下图


block内部结构图

block内部只有两个参数,一个impl,一个Desc,而函数的调用地址 - FuncPtr是再impl中的,为什么这里能直接这样写呢?

因为,__main_block_impl_0 结构的地址和他的第一个成员一样,第一个成员的地址是__block_impl,所以__main_block_impl_0 和 __block_impl 的地址其实是同一个,通过格式强制转换,将 main_block_impl_0 转成 block_impl 就可以直接拿到他内部的 FuncPtr 函数地址,然后进行调用!

本文部分内容转自此篇华文https://www.jianshu.com/p/18f0f7fefea0

相关文章

  • OC基础-Block(1)

    OC基础- blockBlock:本质:一个OC对象,一个封装了函数调用以及函数调用环境的OC对象 先定义一个简单...

  • OC基础-Block(2)

    OC基础-Block(2)Block的变量捕获为了保证block内部能够正常访问外部的变量,block有个变量捕获...

  • 托XX福写个Swift闭包教程

    闭包基础知识 Swift闭包和OC的block类似不过还是有点区别 OC的block是一个匿名函数 Swift 中...

  • OC 基础-Block类型

    OC基础-Block(3)Block的类型Block有三种类型,可以通过调用class方法或者isa指针查看具体类...

  • iOS 面试题(一)

    基础题:1.在oc中如何实现深度拷贝2.请描述什么是delegate、block、NSNotification,他...

  • 2019 知识点总结

    1、Block 释放 追问 (1)Block本质? Block本质就是一个OC对象,内部有isa指针。 Block...

  • Block常见用法的理解

    How To Use OC Block Part1 Block简述 Block作为语言特性 在Mac OS X 1...

  • swift 调用 OC中的block

    OC中声明block; OC中实现block swift中实现

  • block底层原理

    1.block 本质 block本质是一个oc对象,内部含有isa指针block是封装了函数调用以及调用函数的OC...

  • OC底层基础:Block

    查看oc文件底层结构 支持ARC、指定运行时系统版本 一、__block修饰符 1. __block可以用于解决...

网友评论

      本文标题:OC基础-Block(1)

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