iOS面试题(二十三)Block--Block的本质&截获变量特性&__block修饰

6.Block

  • Block的本质(什么是Block,你对Block的调用又是怎样理解的)
  • 截获变量特性(系统关于Block的截获变量特性又是怎样实现的呢)
  • __block修饰符的本质(在什么情况下使用)
  • Block的内存管理(说明时候需要对一个Block进行copy操作?栈Block和堆Block你又是否了解呢?)
  • 循环引用(Block在使用不当的时候,经常会产生的循环引用)

Block的本质

int multiplier = 6
int(^ Block)(int) = ^int(int num){
      return num* multiplier
};
Block(2);

从源码来分析一下,通过clang命令行工具中的-rewrite-objc参数[clang -rewrite-objc file.m],我们可以把OC代码转化为C++的实现

什么是Block?



Block是一个对象,封装了函数及其执行上下文
Block是将函数及其执行上下文封装起来的对象

内部有isa指针和FuncPtr函数指针

isa说明他是个对象,FuncPtr指针指向了函数实现

什么是Block调用:

Block调用既是函数的调用。

当我们调用block(2)时,内部实现是

通过block结构体里面的函数指针,取出对应的执行体.将参数传递进来(block本身,2),然后进行内部调用

 

截获变量特性

先看一个问题

// 全局变量
int global_var = 4;
// 静态全局变量
static int static_global_var = 5;

- (void)method
{
     int multiplier = 6;
    int(^Block)(int) = ^int(int num)
    {

        return num * multiplier;
    };
    multiplier = 4;
    NSLog(@"result is %d", Block(2));
}


输出是什么--->"result is 12"? 
 如果 将 int multiplier 改为静态变量 static  int multiplier = 6, 结果又是什么?

带着问题往下看,针对不同类型的对象,block对其截获的特点也是不一样的。

  • 局部变量 -- 基本数据类型 , 对象类型 (对于基本数据类型的局部变量截获其值,对于对象类型的局部变量连同 所有权修饰符 一起截获)
  • 静态局部变量 ( 以指针形式截获局部静态变量 )
  • 全局变量 (不截获全局变量)
  • 静态全局变量 (不截获静态全局变量)

从这段代码来深入了解一下

int global_var = 4;
static int static_global_var = 5;

-(void)method1
{
    int var = 1;
    __unsafe_unretained id unsafe_obj = nil;
    __strong id strong_obj = nil;
    static int static_var = 3 ;
    void(^block)(void) = ^{
        
        NSLog(@"局部变量<基本数据类型> var %@",var);
        NSLog(@"局部变量<__unsafe_unretained 对象类型> var %@",unsafe_obj);
        NSLog(@"局部变量< __strong 对象类型> var %@",strong_obj);
        NSLog(@"静态变量 %d",static_var);
       
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值