block原理

block的本质是一个结构体,包含引用的外部变量及一个需要执行的函数的函数指针,在内存中可以有三个位置,即堆上、栈上和全局区(静态区)。当block中没有引用外部变量时,block的位置在全局区,当block中访问外部变量时,MRC下block默认在栈区,ARC下block默认会从栈区复制到堆区。

另外,block在生成对应的结构体时,如果引用的外部变量是strong类型的,那么在结构体内部生成的对应成员变量就是strong类型的;如果引用的外部变量是weak类型的,那么在结构体内部生成的对应的成员变量就是weak类型的;如果是基本类型的,那么生成的对应的成员变量就是基本类型的。block的函数在执行时,会在函数体内部创建局部变量,赋值成对应的block结构体内的成员变量,然后再用这些局部变量去做对应的操作,这也是普通情况下(外部变量不加__block关键字)block内部不能改变外部变量的原因。所以block在创建的时候实际上就已经对其中引用的外部变量有内存操作了(strong类型的引用计数会加1),在block的函数体执行过程当中,外部变量的引用计数也会有相应的增减。

__block关键字原理

通常情况下,block的函数体中是不能更改引用的外部变量的值的(但是可以改这个变量的某个属性值,如果这个变量是个OC类型的变量,因为对象还是同一个对象),但是如果外部变量用了__block关键字修饰,那么block函数体内部就可以更改这个外部变量的值。原理是在加了__block关键字之后,这个变量会变成一个结构体中的一个成员变量,之后我们再访问这个外部变量的时候实际上是在访问这个结构体里对应的成员变量。结构体中会有一个forwarding指针,访问成员变量时都会通过这个forwarding指针,当这个变量在栈上时forwarding指针指向结构体自身,当这个变量被复制到堆上时栈上的结构体的forwarding指针指向堆上的这个结构体,堆上的结构体的forwarding指针还是指向自身,forwarding指针的作用就是在操作外部变量时,无论是通过栈上的结构体还是堆上对应的结构体,都能够操作同一个外部变量(即堆上的结构体中的成员变量)。

举个例子:

-(void)viewDidLoad {

__block int a = 1;  //栈上的变量结构体(简称a结构体)

a++;      // a结构体->forwarding->a++;这时候forwarding指向的是自己

self.myBlock = ^{//a结构体被赋值给block结构体中的成员变量,假设为a1结构体

a++;       //block结构体->a1结构体->fowrding->a++;

};

a++;     //a结构体->fowrding->a++; 这时候forwarding指向的是堆上的结构体

}

-(IBAction)clickButton {

self.myBlock();   //block结构体->a1结构体->fowrding->a++;

}

原理很简单:就是block结构体会创建内部成员变量保存外部变量,当外部变量被__block关键字修饰时会生成一个对应的变量结构体,block结构体对应的内部成员变量会变成这个变量结构体。(相当于是block结构体保存了__block修饰的外部变量的一个间接引用)

block原理的更多相关文章

  1. 转:Block原理及引用循环问题

    2010年WWDC发布iOS4时Apple对Objective-C进行了一次重要的升级:支持Block.说到底这东西就是闭包,其他高级语音例如Java和C++已有支持,第一次使用Block感觉满简单好 ...

  2. 深入浅出-iOS Block原理和内存中位置

    Posted by 微博@Yangsc_o 原创文章,版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0 #简介 今天回顾一下blcok,基本 ...

  3. iOS之Block总结以及内存管理

    block定义 struct Block_descriptor { unsigned long int reserved; unsigned long int size; void (*copy)(v ...

  4. iOS之block,一点小心得

    作为一个iOS开发程序员,没用过block是不可能的.这次我探讨的是block原理,但是有些更深层次的东西,我也不是很清楚,以后随着更加了解block将会慢慢完善. 第一个问题,什么是block? 我 ...

  5. block注意事项

    1.block的声明和注意事项 #import "ZYViewController.h" @interface ZYViewController () @end /*用typede ...

  6. fir.im Weekly - 一切从知识重构开始

    一年之计在于春,大自然开始了新元素的重构.你的知识库是否也该重构更新呢? 本期 fir.im Weekly 包含最新的Android.iOS 开发工具.源码和好玩的UI 动画分享,希望对你有用. Sw ...

  7. POJ 1523 (割点+连通分量)

    题目链接:http://poj.org/problem?id=1523 题目大意:连通图,找图中割点,并计算切除该割点后,图中的连通分量个数. 解题思路: POJ的数据很弱. Tarjan法求割点. ...

  8. MyQQ 前言

    从接触IOS以来也将近8个月了,学习了不少知识. 看了一系列的书籍如: <objective-c 开发入门>--语法介绍,学习一门语言是开发的基础.所以这是我大致对语法语句学习的锻炼地方, ...

  9. ARC下需要注意的内存管理

    ARC下需要注意的内存管理 2016/04/03 · iOS开发 · 内存管理 分享到:1 原文出处: 一不(@luoyibu)    之前发了一篇关于图片加载优化的文章,还是引起很多人关注的,不过也 ...

随机推荐

  1. 学习笔记之Supervised Learning with scikit-learn | DataCamp

    Supervised Learning with scikit-learn | DataCamp https://www.datacamp.com/courses/supervised-learnin ...

  2. 廖雪峰Java2面向对象编程-4抽象类和接口-2接口

    1.接口的定义 抽象方法本质上是定义接口规范. 在抽象类中定义了一个抽象方法,子类中必须实现这个抽象方法. public abstract class Person{ public abstract ...

  3. rhel7.0解决:This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.

    看这篇文章前,先说一下我的实际情况.本来要部署docker服务的,然后yum安装任何软件都不起效果,最后通过老师远程的帮助,最后成功安装上docker,老师的解决办法就是忽略这个问题,直接自己配置网络 ...

  4. [UE4]虚幻4 spline组件、spline mesh组件的用法

    最近公司项目需要,把这两个东东好好看了下.不得不说,这两个组件还是非常方便的,但是相关的介绍.教程却非常的少.它们概念模糊,用法奇特,我就总结下吧. 首先,先要明白spline component.s ...

  5. 小程序踩坑异步请求json时,headers设置 "content-type": "application/x-www-form-urlencoded"

    wx.request({ url: url, method:params.method, data: params.data, header: { "content-type": ...

  6. ArcGIS for android访问天地图

    底图采用Web Mercator投影坐标系 获取元数据信息:http://t0.tianditu.com/img_w/wmts?SERVICE=WMTS&REQUEST=GetCapabili ...

  7. oracle基础语句学习

    1.寻找公司所有部门信息 select * from dept; 2.寻找特定列 select dept_name from dept; 3.使用列别名 基本书写方法:列名 列别名 列名 as 列别名 ...

  8. 03-String常用方法

    1.获取方法 /* * 编辑:刘诗华 int length() 获取字符串的长度 char charAt(int index) 获取特定位置的字符 (角标越界) int indexOf(String ...

  9. 通过Xshell来访问和连接Linux

    Xshell初使用:Xshell资源下载 刚刚接触Xshell是在javamail中的telnet收发邮件,然而这个我们并不常用,用的最多的是Xshell进行访问和连接远程主机. 通过Xshell来访 ...

  10. requests模块的cookie和代理操作

    一.基于requests模块的cookie操作 引言:有些时候,我们在使用爬虫程序去爬取一些用户相关信息的数据(爬取张三“人人网”个人主页数据)时,如果使用之前requests模块常规操作时,往往达不 ...