iOS---Block总结

Q: 什么是Block?
A: Block是将函数及其执行上下文封装起来的对象。

Q: 怎样理解Block调用?
A: Block调用就是函数的调用

Q: Block的一大特性是截获变量,那么系统关于Block截获变量是怎样实现的?
Q: 会使用__block修饰符,这修饰符用于做什么?
Q: 什么时候需要对Block进行copy操作?
Q: 栈Block,堆Block是否了解?


image.png
image.png
image.png

isa指针,是Block是对象的标志
FuncPtr是函数指针,会指向具体的函数实现。
通过函数指针,得到相应的函数执行体。


image.png

截获变量

image.png
image.png

Q:对Block截获变量的特性是否有了解?
A:
1).对于基本数据类型的局部变量截获其值 (值类型)
2).对于对象类型的局部变量连同所有权修饰符一起截获(例如__unsafe_unretained id unsafe_obj = nil;
__strong id strong_obj = nil; 循环引用跟所有权修饰符一起截获是有关的)
3).以指针形式截获局部静态变量(引用类型)
4).不截获全局变量,静态全局变量

__block修饰符

  • 一般情况下,对被截获变量进行赋值操作,需要加__block修饰符


    image.png

1.使用,不需要__block


image.png

2.赋值,需要__block


image.png

3.对变量赋值,需要__block


image.png

4.对变量赋值,不需要__block


image.png

__block修饰的变量变成了对象

image.png
image.png

栈上的__forwarding指针指向自己。

__forwarding指针是用来做什么的?

Block内存管理

image.png
image.png

Q:何时需要对block进行copy操作?

image.png

对于不同类型的block, copy的结果也不一样。


image.png
image.png

Q:当对栈上block进行copy操作后,在MRC环境下,是否会引起内存泄漏呢?
A:会。copy操作后, 堆上的block没有其他额外的成员变量指向它,跟alloc出一个对象,没有给出相应的release操作一样,产生内存泄漏。

栈上__block变量的copy

image.png

Q:栈上的__forwarding指针的用处?
A: 栈上的__forwarding指针指向的是堆上的block变量,堆上的__forwarding指针指向的是自身。


image.png

如果要修改栈上block,如果做过copy操作,实际上修改的就不是栈上的__forwarding对应的值,而是通过通过栈上block的__forwarding指针找到堆上的__forwarding变量,然后对堆上的multiplier值进行修改,比如改成4。
同样的,如果是__block变量,由于被成员变量持有,当我们在其他地方调用__block变量的修改,实际是通过自身的__forwarding指向来修改的。

__forwarding存在的意义

Block循环引用

image.png
image.png

由于block对其截获的变量,是连其所有权修饰符一并截获。
因此,block内部的持有的变量,也是__weak类型。

Q:以下代码有什么问题?


image.png

A:在MRC下,不会产生循环引用,在ARC下,会产生循环引用,引起内存泄漏。

image.png
image.png

这个解决方案的原理是,在block内部把blockSelf置为nil,从而断开了对对象的持有。但是有一点很重要,如果一直不调用block, 就没机会断开对象的持有,也就无法解决循环引用了

总结

Q:为什么block会产生循环引用?
A:当前block对当前某一对象进行截获,block会对对应变量强引用,当前block又由于当前对象对其有一个强引用,因此就产生了一种自循环引用的循环引用问题,可以声明为__weak变量来进行循环引用消除。如果定义了__block修饰符,一种是在MRC下,MRC不会产生循环引用,一种是在ARC下,可以通过断环的方式解除对应循环引用。有一个弊端,如果block一直不能被调用,循环引用是不能被解除的。

Q:你都遇到过哪些循环引用,是怎么解决的?
A:
1). NSTimer
2). block循环引用, __weak解除

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容

  • 前言:Block 是开发过程中常用便捷的回调方式,本文简单介绍 Block 一、Block 简介 Block 对象...
    梦蕊dream阅读 4,731评论 5 26
  • 前言 Blocks是C语言的扩充功能,而Apple 在OS X Snow Leopard 和 iOS 4中引入了这...
    小人不才阅读 3,757评论 0 23
  • 栈对象、堆对象 栈是一块保存局部变量或函数参数值的内存区域。在现代的操作系统中,每个线程都有一个对应的栈。当函数调...
    HoooChan阅读 2,692评论 0 14
  • 默认情况下,在block中访问的外部变量是复制过去的,即:写操作不对原变量生效。但是你可以加上 __block 来...
    sunnyxg0812阅读 521评论 0 1
  • iOS的block是对c语言的一个扩展,它与c语言的函数指针是相似的,但是两者也存在以下区别:1.block的代码...
    彬至睢阳阅读 361评论 0 2