block 解析 - 简介
简介
block 类似标准的c函数,除了一些函数体一些可执行的代码,还可以把变量绑定到自动栈或者托管堆上.....和js里的闭包、c# lambda表达式有些类似,实质是一个函数指针。与函数指针的区别在于其可以捕获(capture)其定义时作用域内的变量。
Block objects are a C-level syntactic and runtime feature. They are similar to standard C functions, but in addition to executable code they may also contain variable bindings to automatic (stack) or managed (heap) memory. A block can therefore maintain a set of state (data) that it can use to impact behavior when executed.
void(^Test)(void)=^{ printf("%s","hello world!"); };
在Objective-C语言中,一共有3种类型的block(可通过isa指针打印查看):
1._NSConcreteGlobalBlock 全局的静态block,不会访问任何外部变量。
2._NSConcreteStackBlock 保存在栈中的block,当函数返回时会被销毁。
3._NSConcreteMallocBlock 保存在堆中的block,当引用计数为0时会被销毁。
需要注意的是ARC下,没有栈block,尝试打印block对象,的确没有看到MallocBlock,但是通过clang反编译看到isa还是指向的_NSConcreteStackBlock。
结构
一个block其实是一个对象,有他自己的属性,结构如下

- isa指针,所有对象都有该指针,用于实现消息传递等功能(ias一般指向父类、元类)
- flags,用于按bit位表示一些block的附加信息
- reserved,保留变量。
- invoke,函数指针,指向具体的block实现的函数调用地址。
- descriptor, 表示该block的附加描述信息,主要是size大小,以及copy和dispose函数的指针。
- variables,capture过来的变量,block能够访问它外部的局部变量,就是因为将这些变量(或变量的地址)复制到了结构体中。
变量
block支持全局变量、静态变量、全局的函数、局部变量、封闭的参数,而且支持两种其他变量的类型__block修饰符(读写)、只读。
引用官方文档:
Within the block object’s body of code, variables may be treated in five different ways.
You can reference three standard types of variable, just as you would from a function:
- Global variables, including static locals
- Global functions (which aren’t technically variables)
- Local variables and parameters from an enclosing scope
Blocks also support two other types of variable:
- At function level are __block variables. These are mutable within the block (and the enclosing scope) and are preserved if any referencing block is copied to the heap.
- const imports.
block变量使用规则:
- 全局变量,包括静态变量可以直接在block使用(block内可以直接修改,注意内存,会有强引用)
- block参数传递,类似函数参数
- 存在栈上的变量(非静态的),即局部变量。这些变量将会被截获,他们将会被block引用,他们的值是在初始block之前截获最近的一次
- 定义在封闭区间的本地变量(局部变量),用__block修饰符,是可以修改的,任何的更改将会反应到封闭的区间,包括任何引用到的block
- block内部定义的变量,和函数内部定义的变量一样。
引用官方文档:
The following rules apply to variables used within a block:
- Global variables are accessible, including static variables that exist within the enclosing lexical scope.
- Parameters passed to the block are accessible (just like parameters to a function).
- Stack (non-static) variables local to the enclosing lexical scope are captured as const variables.Their values are taken at the point of the block expression within the program. In nested blocks, the value is captured from the nearest enclosing scope.
- Variables local to the enclosing lexical scope declared with the __block storage modifier are provided by reference and so are mutable.Any changes are reflected in the enclosing lexical scope, including any other blocks defined within the same enclosing lexical scope. These are discussed in more detail in “The __block Storage Type.”
- Local variables declared within the lexical scope of the block, which behave exactly like local variables in a function. Each invocation of the block provides a new copy of that variable. These variables can in turn be used as const or by-reference variables in blocks enclosed within the block.
后续会详细介绍block的各种变量使用。
block 解析 - 简介的更多相关文章
- iOS开发之网络数据解析(二)--XML解析简介
前言:本篇随笔介绍的是XML解析. 正文: 1.XML解析方式有2两种: DOM:一次性将整个XML数据加载进内存进行解析,比较适合解析小文件 SAX:从根元素开始,按顺序一个元素一个元素往下解析,比 ...
- Block解析(iOS)
1. 操作系统中的栈和堆 我们先来看看一个由C/C++/OBJC编译的程序占用内存分布的结构: 栈区(stack):由系统自动分配,一般存放函数参数值.局部变量的值等.由编译器自动创建与释放.其操作方 ...
- iOS开发之网络数据解析(一)--JSON解析简介
前言:对服务器请求之后,返回给客户端的数据,一般都是JSON格式或者XML格式(文件下载除外) 本篇随便先讲解JSON解析. 正文: 关于JSON: JSON是一种轻量级的数据格式,一般用于数据交互 ...
- block 解析 - 内存
block结构体相应的也有一个成员引用,这样会增加对局部变量的 _para1引用,在Block销毁的时候引用就释放掉了 我们了解到了用__block修饰的变量,可以在block内部修改,__block ...
- block 解析 - 成员变量
回顾 在 上一篇 中我们讲了截获变量特性,对于局部变量,变量不加__block修饰符,在block内部是无法修改变量的值.而且 对值类型的修改,如果block初始化后,无法同步到block内部 对于指 ...
- block 解析 - 局部变量
局部变量 block内使用局部变量,一般都是截获变量(只读),截获离block初始化最近的一次的值. 引用官方文档: Stack (non-static) variables local to the ...
- block 解析 - 形参变量
block形参 之前漏了一篇block形参的介绍,这里给补上. block形参就是定义block带的参数,和函数的参数使用一样,我们可以在block随意使用修改block形参. 我们来看个例子: 我们 ...
- block 解析 - block变量
block变量 上一篇 讲的是block静态变量的特性,这里我们来看一下_block变量.引用官方: You can specify that an imported variable be muta ...
- block 解析 - 静态变量
静态变量 上一篇 我们了解了block全局变量的使用,静态变量和全局变量一样,可以直接在block内部使用,也可以在block内部修改 引用官方文档: Global variables are acc ...
随机推荐
- hdoj 1233 还是畅通工程(最小生成树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1233 思路分析:该问题为最小生成树问题,使用kruskal算法或者prim算法即可解决: 代码如下: ...
- HDOJ 1429 胜利大逃亡(续) (bfs+状态压缩)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1429 思路分析:题目要求找出最短的逃亡路径,但是与一般的问题不同,该问题增加了门与钥匙约束条件: 考虑 ...
- PHP中用到的一些字符串函数
/*常用的字符串输出函数 * * echo() 输出字符串 * print() 输出一个或多个字符串 * die() 输出一条信息,并退出当前脚本 * printf() ...
- 讲讲金融业务(一)--自助结算终端POS
之前在群里和大家聊天的时候,发现好多人对银行业务比較感兴趣,或许是由于大家对银行不了解,以为非常神奇的样子.全部,从这周開始我打算把我肚子里的墨水慢慢地倒出来,和大家分享分享. 在技术还不发达的时 ...
- 把Web Form项目转换成MVC项目
http://umbraco.com/follow-us/blog-archive/2013/7/14/moving-from-webforms-to-mvc.aspx https://codinga ...
- Java基础之编程语法(一)
1.基本格式 所有Java代码都应该在一个class中. Java是严格区分大小写的. Java是一种自由格式的语言.Java代码分为结构定义语句和功能执行语句,功能执行语句最后必须以分号结束. 2. ...
- dialog组件的jquery封装实现
(function($){ $.extend({ Dialog : function(id, options){ var option = $.extend({}, options); option. ...
- qt 操作word
//修改doc QString filepath="e:\\aa.doc"; QAxWidget *word = new QAxWidget("Word.Applicat ...
- notify()、notifyAll()和wait()
看到一道面试题,写一个多线程程序,交替输出1.2.1.2…… 先写下程序: /** * Created by Andrew on 2015/10/28. */ public class OutputT ...
- 编译:一个 C 程序的艺术之旅(转载)
C 程序为什么要编译才能执行?一个 C 程序在变成可执行文件的过程中,为什么要经过预处理.编译.汇编.链接这四道工序?让我们从这段简单的 C 程序开始. 为什么要编译 这并不是一个简单的问题.我们知道 ...