问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

iOS开发面试拿offer攻略之block篇

发布网友 发布时间:2022-10-12 16:44

我来回答

1个回答

热心网友 时间:2023-10-23 04:19

Block 是将函数及其执行上下文封装起来的对象。 比如:

通过 clang -rewrite-objc WYTest.m 命令编译该 .m 文件,发现该 block 被编译成这个形式:

其中 WYTest 是文件名, blockTest 是方法名,这些可以忽略。其中 WYTest blockTest_block_impl_0 结构体为

--block_impl 结构体为

block 内部有 isa 指针,所以说其本质也是 OC 对象

block 内部则为:

所以说 Block 是将函数及其执行上下文封装起来的对象

既然 block 内部封装了函数,那么它同样也有参数和返回值。

如果你正在跳槽或者正准备跳槽不妨动动小手,添加一下咱们的交流群1012951431来获取一份详细的大厂面试资料为你的跳槽多添一份保障。

这里的输出是 6 而不是 2,原因就是对局部变量 num 的截获是值截获。同样,在 block 里如果修改变量 num ,也是无效的,甚至编译器会报错。

打印为 1,2,3

局部对象变量也是一样,截获的是值,而不是指针,在外部将其置为 nil ,对 block 没有影响,而该对象调用方法会影响

输出为 2,意味着 num = 1 这里的修改 num 值是有效的,即是指针截获。同样,在 block 里去修改变量 m ,也是有效的。

编译后

( impl.isa = &_NSConcreteStackBlock ;这里注意到这一句,即说明该 block 是栈 block )

可以看到局部变量被编译成值形式,而静态变量被编成指针形式,全局变量并未截获。而 --block 修饰的变量也是以指针形式截获的,并且生成了一个新的结构体对象:

该对象有个属性: num5 ,即我们用 --block 修饰的变量。这里 --forwarding 是指向自身的(栈 block )。

一般情况下,如果我们要对 block 截获的局部变量进行赋值操作需添加 --block 修饰符,而对全局变量,静态变量是不需要添加 --block 修饰符的。

另外, block 里访问 self 或成员变量都会去截获 self 。

分为全局 Block(_NSConcreteGlobalBlock) 、栈 Block(_NSConcreteStackBlock) 、堆

Block(_NSConcreteMallocBlock) 三种形式

其中栈 Block 存储在栈 (stack) 区,堆 Block 存储在堆 (heap) 区,全局 Block 存储在已初始化数据 (.data) 区

输出:

比如:

输出:

日常开发常用于这种情况:

比如堆 1中的全局进行 copy 操作,即赋值:

输出:

仍是全局 block

而对 2中的栈 block 进行赋值操作:

输出:

对栈 blockcopy 之后,并不代表着栈 block 就消失了,左边的 mallock 是堆 block ,右边被 copy 的仍是栈 block 比如:

输出:

即如果对栈 Block 进行 cop ,将会 copy 到堆区,对堆 Block 进行 copy ,将会增加引用计数,对全局 Block 进行 copy ,因为是已经初始化的,所以什么也不做。

另外, --block 变量在 copy 时,由于 --forwarding 的存在,栈上的 --forwarding 指针会指向堆上的-- forwarding 变量,而堆上的 --forwarding 指针指向其自身,所以,如果对 --block 的修改,实际上是在修改堆上的 --block 变量。

即 --forwarding 指针存在的意义就是,无论在任何内存位置,都可以顺利地访问同一个 --block 变量

另外由于 block 捕获的 --block 修饰的变量会去持有变量,那么如果用 --block 修饰 self ,且 self 持有

block ,并且 block 内部使用到 --block 修饰的 self 时,就会造成多循环引用,即 self 持有 block , block 持有 --block 变量,而 --block 变量持有 self ,造成内存泄漏。

比如:

如果要解决这种循环引用,可以主动断开 --block 变量对 self 的持有,即在 block 内部使用完 weakself 后, 将其置为 nil ,但这种方式有个问题,如果 block 一直不被调用,那么循环引用将一直存在。

所以,我们最好还是用 --weak 来修饰 self

以上就是 block 篇的面试题合集了,感谢观看~!

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
"你是在哪看到我的照片?"怎么说英语 留恋地看着我的照片用英语怎么说? 高德iphone地图下载 苹果手机高德地图怎么下载地图 孕中期适合出游吗 哪些孕妇不适合长途旅行 孕妇坐长途车旅行的好处 孕妇出游的最佳时间 孕晚期适合出游吗 孕妇外出旅行禁忌 小米11烧wifi啥表现 如何在iOS中使用Block──How to use Blocks with iOS 这一次美股会不会重蹈覆辙 森萨塔科技(宝应)有限公司的公司发展: 比熊一般穿16码衣服 大概穿多大的鞋呢 想在网上买点花种子,淘宝上乱七八糟的店太多了,请问有什么好的店铺推荐吗? 宝宝7天不大便怎么办 出生6天的宝宝两天没有大便怎么办 老是有黑眼圈是身体哪里出了问题 电脑字体重影模糊不清怎么回事 _ _ash应该怎么填 顺丰快递,从广东深圳到福建省泉州永春呈祥乡要几天? 福建呈祥有机公社农业有限公司怎么样? 厦门到永春呈祥有多远 呈祥乡的介绍 永春县城和呈祥乡呈祥村有几公里 牙疼,有炎症,吃药2天因为受不了硬要去拔牙,结果打麻药不管用,硬要医生拔下来的,输液4天了,有点感染 我的后牙疼的厉害,后牙一颗牙中间已经破损,要是拔牙换牙的话得需要多少钱 在河北邢台矫正牙需要多钱?19岁,需拔一颗牙。。。 邢台眼科医院住院拔牙可以医保吗? 邢台拔智齿要多少钱 photoshop图像处理软件花钱吗? 我有一个朋友做微信投票员,但她微信没有绑定卡,如果只用发微信红包这样的形式可以做投票员吗 可以在微信投票系统发红包吗? 微信上让我投票给我红包,他们是从哪接的任务 股价低于正股怎么办 手机里pilrexpress里把头像背景虚化,怎样增加一张图片 显卡Intel(R) G41 Express Chipset (1024 MB) 可以换成独立的吗? 主板型号 联想主板 芯片组 英特尔 P35/G33/G31/P31 Express - ICH7 BIOS 联想 51KT54AUS能用什么样的CPU啊 CPU 英特尔 第三代酷睿 i7-3770 @ 3.40GHz 四核 主 板 技嘉 Z77P-D3 (英特尔 Ivy Bridge - Z77 Express 爱酷8是国产屏幕吗 爱酷8和爱酷8pro的区别 一年过去了,英特尔还在遭受“幽灵”和“熔毁”的困扰 想自学数据库,零基础,怎么学 Cortex-A9成本敏感什么意思 深圳北大青鸟分享零基础学习Java有哪些步骤? 美兰北大青鸟分享零基础学习Java有哪些步骤? 航天桥北大青鸟分享零基础学习Java有哪些步骤? 佳音北大青鸟分享零基础学习Java有哪些步骤? 月经期间吃什么可以排血块,月经有血块是什么引起的 零之轨迹这个任务怎么做