对block的理解

原创 2015年11月20日 16:39:20
  • 参考博客这里

  • block 实际上是Objective-C对于闭包的实现.

block介绍篇


block-struct.jpg

对应的描述如下

struct Block_descriptor {
  unsigned long int reserved;
  unsigned long int size;
  void (*copy)(void *dst, void *src);
  void (*dispose)(void *);
};

struct Block_layout {
void *isa;
int flags;
int reserved;
void (*invoke)(void *, ...);
struct Block_descriptor *descriptor;
};

blcok实际上是有6部分组成:

  • isa 指针,所有对象都有该指针,用于实现对象相关的功能。
  • flags,用于按 bit 位表示一些 block 的附加信息,本文后面介绍 block copy 的实现代码可以看到对该变量的使用。
  • reserved,保留变量。
  • invoke,函数指针,指向具体的 block 实现的函数调用地址。
  • descriptor, 表示该 block 的附加描述信息,主要是 size 大小,以及 copy 和 dispose 函数的指针。
  • variables,capture 过来的变量,block 能够访问它外部的局部变量,就是因为将这些变量(或变量的地址)复制到了结构体中。
block的类型
  • _NSConcreteGlobalBlock 全局的静态 block,不会访问任何外部变量。
  • _NSConcreteStackBlock 保存在栈中的 block,当函数返回时会被销毁。
  • _NSConcreteMallocBlock 保存在堆中的 block,当引用计数为 0 时会被销毁。
NSConcreteGlobalBlock和NSConcreteStackBlock
void (^globalBlock)() = ^{};
int main(int argc, const char * argv[]) { 
          @autoreleasepool { 
          void (^stackBlock1)() = ^{
 };
 } return 0;
}
对其进行编译转换后得到以下缩略代码
// globalBlock
struct __globalBlock_block_impl_0 {
struct __block_impl impl;
struct __globalBlock_block_desc_0* Desc;
__globalBlock_block_impl_0(void *fp, struct __globalBlock_block_desc_0 *desc, int flags=0) {
    impl.isa = &_NSConcreteGlobalBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
 }
};

//  stackBlock
struct __main_block_impl_0 {
struct __block_impl impl;
struct __main_block_desc_0* Desc;
__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; 
 }
};

int main(int argc, const char * argv[]) {
/* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool;
   void (*stackBlock)() = (void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA); }
   return 0;
};

版权声明:本文为博主原创文章,未经博主允许不得转载。

iOS 对于block的理解

block是对象,它封装了一段代码,这段代码可以在任何时候执行。block可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。它和传统的函数指针很类似,但是有区别:block是inli...
  • worldzhy
  • worldzhy
  • 2014年12月11日 01:22
  • 17255

你真的理解__block修饰符的原理么?

开篇自测在本文的开头,提出两个简单的问题,如果你不能从根本上弄懂这两个问题,那么希望你阅读完本文后能有所收获。 为什么block中不能修改普通变量的值? __block的作用就是让变量的值在block...
  • abc649395594
  • abc649395594
  • 2015年07月27日 19:26
  • 9009

《Inode与Block重要知识总结核心讲解》

1.查看/dev/sda1下磁盘分区的block大小: 2.查看单个inode及block大小: 3.有关inode的知识: Inode 用户的属性信息: ①首页的目录索引就相当于Inod...
  • BlackEnn
  • BlackEnn
  • 2016年03月03日 11:21
  • 2407

__block 与 __weak的区别理解

Block理解: Block可以访问局部变量,但是不能修改 如果修改局部变量,需要加__block __block int multiplier = 7; int (^myBlo...
  • LitleLee1005
  • LitleLee1005
  • 2016年10月09日 22:09
  • 77

关于iOS的block块代码的理解

在学习和使用block的这段时间, 从难以理解到现在勉强会用, 有了自己的一套理解, 希望能够帮助大家学习block, 因为block块常用于OC的方法中, 所以举了个例子来说明: ...
  • XjingweiU
  • XjingweiU
  • 2014年11月05日 00:36
  • 463

使用 Unity Application Block(三):理解和使用依赖注入的键

在使用 Unity 创建对象之前,需要准备 Unity 容器,也即进行注册(类型映射)。在 使用Unity(二):配置 Unity 、读取配置信息和获取对象中, 我们学习了如何使用配置文件来进行注...
  • CNHK1225
  • CNHK1225
  • 2014年09月17日 16:45
  • 895

iOS 对于block的理解

block是对象,它封装了一段代码,这段代码可以在任何时候执行。block可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。它和传统的函数指针很类似,但是有区别:block是inli...
  • worldzhy
  • worldzhy
  • 2014年12月11日 01:22
  • 17255

iOS开发之 __block 与 __weak的区别理解

资料来源1 资料来源2__block对象在block中是可以被修改、重新赋值的。使用了__weak修饰符的对象,作用等同于定义为weak的property。自然不会导致循环引用问题,因为苹果文档已经...
  • wtdask
  • wtdask
  • 2017年07月28日 10:32
  • 210

如何利用block回调--神级理解

我们在开发中常常会用到函数回调,你可以用通知来替代回调,但是大多数时候回调是比通知方便的,所以何乐而不为呢?如果你不知道回调使用的场景,我们来假设一下: 1.我现在玩手机 2.突然手机没有电了 3.我...
  • xyzs996
  • xyzs996
  • 2013年10月10日 14:51
  • 704

iOS 代理和block的理解

首先两者作用是一样的,都是进行单一回调。不通的是,delegate是个对象,然后用过一个对象自己调用代理协议函数来完成整个流程。block是传递一个函数指针,利用函数指针执行来进行回调。还有在内存管理...
  • sinat_35710100
  • sinat_35710100
  • 2017年02月06日 16:04
  • 143
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:对block的理解
举报原因:
原因补充:

(最多只允许输入30个字)