对于大多数人来说,block内部究竟是怎样实现的呢?咱们能够借助clang将其编译成为c++的代码,就能够看出,block究竟是什么东西,c++
先来看这样一个问题,函数
<!-- 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,第二个输出的是30code
要想知道这里面干了些什么!须要咱们将其编译成为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;
}it
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的区别 但愿能对读者有用!