博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入学习block
阅读量:6180 次
发布时间:2019-06-21

本文共 2778 字,大约阅读时间需要 9 分钟。

首先,什么是block?block其实就是一个代码块,把你想要执行的代码封装在这个代码块里,等到需要的时候再去调用。那block是OC对象吗?答案是肯定的。

做一道很简单的关于block的测试题:

int (^testBlock)   (int) = ^(int num) {      return num++;    };    NSLog(@"%d", testBlock(testBlock(testBlock(3))));

这道题是我公司面试题中的一道,来面试的都是至少两年工作经验的,但是很郁闷,这道题绝大多数人写的都是6。。正确结果为:3。

以下讲解的内容均是ARC环境下。

 

一、block的分类

  • NSStackBlock:栈block

  • NSMallocBlock:堆block

  • NSGlobalBlock:全局block

1.NSStackBlock:

特点:生命周期由系统控制,函数返回即销毁

用到局部变量、成员属性\变量,且没有强指针引用的block都是栈block

int (^testBlock)   (int) = ^(int num) {      return num++;    };    NSLog(@"%d", testBlock(testBlock(testBlock(3))));

 

注意:不是没有强指针(copy或strong)引用的block,就是栈block,也有可能是全局block(下面会介绍什么是全局block)。

2.NSMallocBlock:

特点:没有强指针引用即销毁,生命周期由程序员手动管理

栈block如果有强指针引用或copy修饰的成员属性引用就会被拷贝到堆中,变成堆block

//堆block int j = 0;     void(^mallocBlock)() = ^ {        NSLog(@"%d",j);    };    NSLog(@"%@",mallocBlock);//输出结果 <__NSMallocBlock__: 0x7f8cd351db80>

 

上面代码也没用看到strong 或 copy修饰符,但是为什么会强引用的,因为在ARC环境下,我们在声明变量的时候,前面是会被默认加上 __strong 修饰符的。所以我们在ARC下声明的Block一般都是堆block。

3.NSGlobalBlock: 

特点:命长,有多长?很长很长,人在塔在(应用程序在它就在)

没有用到外界变量,或者只用到全局变量、静态(static)变量的block就是全局block

对于全局block,用weak,strong,还是copy修饰都是可以的。(但最好不用用weak)

//全局block    void (^globalBlock) () = ^ {        NSLog(@"%d",staticNum);    };    NSLog(@"%@",globalBlock); //输出结果 <__NSGlobalBlock__: 0x108152110>

 

注意:如果block中没有用到外界变量,不管他是用什么修饰符修饰,他都是全局block!

例如:

void (^global2Block) () = ^ {        NSLog(@"globalBlock");    };    NSLog(@"%@",global2Block); // 输出结果 <__NSGlobalBlock__: 0x1023a0150>

二、block对外界变量的捕获

1.1 基本数据类型:局部变量

     block会拷贝该变量的值当做常量使用,外界修改变量的值不会影响block内部,且block内部不能对其修改

     block内部修改外界变量i的值直接报错,如果想要修改,可以在int a = 0前面加上关键字__block,此时i等效于全局变量或静态变量

 

int a = 0;       void (^block1)() = ^ {         NSLog(@"a = %d",a);    };    a++;    block1(); //输出结果 a = 0;        __block int b = 0;       void (^block2) () = ^ {        NSLog(@"b = %d",b); // 输出结果 b = 0;        b = 2;    };    block2();    NSLog(@"b = %d",b); //输出结果 b = 2;

 

1.2 基本数据类型:成员变量(实例变量),静态变量,全局变量

   block直接访问变量地址,在block内部可以修改变量的值,并且外部变量被修改后,block内部也会跟着变

 

self.num = 1;self.num ++;  void (^block3) () = ^ {        self.num++;};block3();NSLog(@"%d",self.num);//输出结果为 3

 

 2.1 指针类型: 局部变量

     block会复制一份指针并强引用指针所指对象,且内部不能修改指针的指向,但是可以修改指针所指向对象的值

 

NSMutableString *str = @"abc".mutableCopy;      void (^block4) () = ^ { //        str = @"def"; 报错      [str appendString:@"def"];      NSLog(@"str = %@",str);    };    str = @"123".mutableCopy;    block4(); //输出结果为 "adbdef"

 

2.2 指针类型: 成员变量(实例变量),静态变量,全局变量

     block不会复制指针,但是会强引用该对象,内部可修改指针指向,block会强引用成员属性\变量所属的对象,这也是为什么block内部用到self.xxx_xxx可能会引起循环引用的原因

 

static NSString *staticStr = @"abc";    void (^block5) () = ^ {        NSLog(@"staticStr = %@",staticStr);        staticStr = @"def";        NSLog(@"staticStr = %@",staticStr);    };    staticStr = @"123";    block5();    //输出结果为 staticStr = 123  staticStr = def

 

 

转载地址:http://jebda.baihongyu.com/

你可能感兴趣的文章
怎么转换音乐格式
查看>>
Object.keys()是按什么顺序返回值的?
查看>>
利用微查询和数据锐化进行大数据探索
查看>>
如何使用视频剪辑软件将qsv格式视频转换为MP4格式
查看>>
原生JS上传图片接收服务器端图片并且显示图片(主要描述blob类型)
查看>>
如何用Python进行数据分析?
查看>>
getDate方法的妙用(js判断闰年)
查看>>
css中的尺寸和单位
查看>>
学Excel函数公式,怎能不会这个组合套路?
查看>>
python之属性描述符
查看>>
GO随笔-搭建一个Web服务器
查看>>
官宣,PyTorch 1.0 稳定版本现已推出
查看>>
最好用的编辑器之一:Vim-Go环境搭建
查看>>
[LeetCode] 803. Bricks Falling When Hit
查看>>
简单聊聊智能硬件的固件测试
查看>>
生物智能与AI——关乎创造、关乎理解(下)
查看>>
Python爬虫 --- 2.5 Scrapy之汽车之家爬虫实践
查看>>
EOSIO 指南(安装CDT)
查看>>
[case52]聊聊flink KeyedStream的aggregation操作
查看>>
微信小程序wepy框架详解(一)
查看>>