iOS开发系列-Block本质篇

概述

在iOS开发中Block使用比较广泛,对于使用以及一些常规的技术点这里不再赘述,主要利用C++角度分析Block内部数据底层实现,解开开发中为什么这样编写代码解决问题。

Block本质

Block本质也是一个OC对象,内部也有isa指针,最终继承NSObject。它是封装了函数调用以及函数调用环境的OC对象。

接下来编写一个Block,利用clang编译器指令可以将我们编写的OC代码转换成C++代码,更好的看清Block地层结构。

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        // 定义block
        void(^block)(void) = ^{
            NSLog(@"-----------");
        };
        
        // 执行block
        block();
    }
    return 0;
}

执行命令

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

上面编写OC代码转换成C++代码main.cpp

#pragma clang assume_nonnull end

struct __block_impl {
    void *isa;
    int Flags;
    int Reserved;
    void *FuncPtr;
};

// Block底层的结构
struct __main_block_impl_0 {
    void *isa;
    int Flags;
    int Reserved;
    void *FuncPtr; // 保存内部代码块执行的函数地址
  // struct __block_impl impl;
    
  struct __main_block_desc_0* Desc; // Block的信息
  // 构造方法
  __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;
  }
};

// Block内部执行代码块封装的函数
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {

     NSLog((NSString *)&__NSConstantStringImpl__var_folders_zz_1js09xx15fz7j7qyrylx4xm80000gn_T_main_3df4b0_mi_0);
}

static struct __main_block_desc_0 {
  size_t reserved;
  size_t Block_size;
} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0)/*block自己结构的内存大小*/};

int main(int argc, const char * argv[]) {
    /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 

        // 定义block
        //  block真实类型  struct __main_block_impl_0 *
        void(*block)(void) = &__main_block_impl_0(__main_block_func_0, &__main_block_desc_0_DATA);

        // 执行block
        block->FuncPtr(block);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/CoderHong/p/10055004.html