selector

面试聊iOS:Block

2021-09-15  本文已影响0人  面试聊iOS

大家好,我是面试聊iOS的程序员。
这篇文章将和大家分享面试iOS时聊Block一般都可以聊些什么。

抖音搜索 面试聊iOS 观看视频版


相关文章链接
面试聊iOS:内存管理
面试聊iOS:RunTime(一)
面试聊iOS:RunTime(二)
面试聊iOS:Block
面试聊iOS:多线程
面试聊iOS:RunLoop
面试聊iOS:性能优化


Block原理

block实际上就是OC对于闭包的实现
闭包是一个函数(或指向函数的指针),再加上该函数执行的外部的上下文变量

block本质上也是一个OC对象,因为它内部有isa指针
block封装了函数调用以及函数调用环境的OC对象

block是一个结构体,通常包含两个成员变量:__block_impl、__block_desc和一个构造函数。

__block_impl {
  void * isa; // isa指针,指向一个类对象,有三种类型
  int Flags; // 负载信息(引用计数和类型信息),按位存储
  void *FuncPtr; // 指向block执行时的函数指针 
}

1、通过block结构体的构造方法生成一个实例,并用一个指针指向当前实例
2、通过block->FuncPtr找到要执行的函数指针


Block类型

NSGlobalBlock 全局block

没有访问外部auto变量(我们平时写的局部变量,默认就有 auto,自动变量,离开作用域就销毁),访问外部static或者全局变量还是全局block

NSStackBlock 栈block

访问了外部auto变量(在ARC下没有强引用指向这个block,而是直接打印出来)

NSMallocBlock 堆block

栈block调用了copy(在ARC下访问了auto变量且有强引用指向该block或作为函数的返回值,就会自动将栈block copy到堆上)

全局block调用copy还是全局block,堆block调用copy引用计数+1


变量捕获

局部变量为什么要捕获?

考虑作用域的问题,在block里属于跨函数来访问局部变量,所以需要捕获

auto变量值传递,static变量指针传递

auto变量可能会销毁,内存可能会消失,不采用指针访问;static变量一直保存在内存中,采用指针访问

全局变量不需要捕获,直接访问
block里访问self会捕获self

OC函数转成C++函数时,self和_cmd作为函数默认传的参数,是局部变量,所以要捕获。
block里访问成员变量是先捕获self,然后通过self访问成员变量


__block、__weak

__block不管是MRC、还是ARC下都可以使用,可以修饰对象,也可以修饰基本数据类型;
__weak只能在ARC下使用,只能修饰对象,不能修饰基本数据类型;
__block对象可以在block中被重新赋值,__weak不可以

解决循环引用

在ARC下使用__weak,在MRC下使用__block

修改变量

__block修饰的变量在block中保存的是变量的地址,使用__block修饰之后的变量类似于static变量
__block不能修饰全局变量、静态变量(static)


weakSelf

如果block在栈空间,不管外部变量是强引用还是弱引用,block都会弱引用访问对象;
�如果block在堆空间,如果外部强引用,block内部也是强引用,如果外部弱引用,block内部也是弱引用

__weak typedof(self) weakSelf = self;

上一篇下一篇

猜你喜欢

热点阅读