block 实现原理详解(一)

本文通过对比普通int变量与__block变量在Block中的表现差异,详细解析了Block在C++中的实现方式,揭示了Block是如何捕获和使用外部变量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://my.oschina.net/panyong/blog/303520

对于大多数人来讲,block内部到底是怎样实现的呢?我们可以借助clang将其编译成为c++的代码,就可以看出,block到底是什么东西,

先来看这样一个问题,

<!-- lang: cpp -->
        int age = 10;
    void (^block)() = ^{
        NSLog(@"%d",age);
    };
    age  = 30;
    block();//10

以及下面的这一段代码

<!-- lang: cpp -->
        __block int age = 10;
    void (^block)() = ^{
        NSLog(@"%d",age);
    };
    age  = 30;
    block();//30

你会发现这两个结果是不同的,第一个输出10,第二个输出的是30

要想知道这里面干了些什么!需要我们将其编译成为C++代码,看下里面到底搞了些什么?使用终端,转到mian.m文件下,使用如下代码 clang -rewrite-objc main.m 将其编译生成 main.cpp文件这时候,我们打开mian.cpp便知 在文件的最底下main函数中

<!-- lang: cpp -->
int main(int argc, const char * argv[])

{

/* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 

    __attribute__((__blocks__(byref))) __Block_byref_age_0 age = {(void*)0,(__Block_byref_age_0 *)&age, 0, sizeof(__Block_byref_age_0), 10};
    void (*block)() = (void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, (__Block_byref_age_0 *)&age, 570425344);
    (age.__forwarding->age) = 30;
    ((void (*)(__block_impl *))((__block_impl *)block)->FuncPtr)((__block_impl *)block);

}
return 0;

}

block内部是调用了一个结构体中的函数: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);}

然后经过分析该c++文件我们知道 block实际上是: 指向结构体的指针 编译器会将block的内部代码生成对应的函数

而在mian.m中,调用普通的int变量时,传过来的age其实是一个值传递,而__block则是引用传递!所以,才是如上的结果!

这是对block的一个基础认识,再接下来的一篇博客中,我讲介绍一下mrc和arc使用block的区别希望能对读者有用!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值