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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS开发面试拿offer攻略之block篇相关的知识,希望对你有一定的参考价值。

参考技术A

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 篇的面试题合集了,感谢观看~!

以上是关于iOS开发面试拿offer攻略之block篇的主要内容,如果未能解决你的问题,请参考以下文章

Java面试之Java基础篇(offer 拿来吧你)

Java面试之数据库篇(offer 拿来吧你)

直面BAT大厂iOS面试攻略

毕业季百度出身大佬总结出来的 98%过率的面试攻略!手把手教你拿下大厂offer!

毕业季百度出身大佬总结出来的 98%过率的面试攻略!手把手教你拿下大厂offer!

iOS 面试全方位剖析 -- Block篇