美文网首页
Block 有三种类型

Block 有三种类型

作者: 昵称nickName | 来源:发表于2018-08-09 10:52 被阅读0次

内存五大内存分区-----堆、栈、自由存储区、全局/静态存储区和常量存储区.
1. 堆,就是那些由new分配的内存块,它们的释放编译器不管,由我们的应用程序控制
2. 栈,就是那些由编译器在需要的时候分配,不需要的时候自动清除的变量的存储区。里面的变量通常是局部变
量、函数参数等。
3. 全局区(静态区) (static) 全局变量和静态变量的存储是放在一起的,初始化的全局变量和静态变量存放在一块区
域,未初始化的全局变量和静态变量在相邻的另一块区域,程序结束后有系统释放。
4. 文字常量区 存放常量字符串,程序结束后由系统释放
5. 程序代码区 存放函数的二进制代码

Block 有三种类型,分别是:

__NSConcreteStackBlock ————————栈中
__NSConcreteGlobalBlock ————————数据区域中
__NSConcreteMallocBlock ————————堆中

ARC下NSStackBlock已经基本不会出现的了, 除非可以强行让它出现,但实际开发中应该不会做这么无聊的事。

先看看一个DEMO。

- (void)viewDidLoad {
[superviewDidLoad];

void(^blockA)() = ^{
NSLog(@"just a block");
    };
NSLog(@"%@", blockA);

int value = 10;
    void(^blockB)() = ^{

NSLog(@"just a block === %d", value);
    };
NSLog(@"%@", blockB);

void(^ __weak blockC)() = ^{
NSLog(@"just a block === %d", value);
    };

NSLog(@"%@", blockC);
}

三个NSLog打印的内容为:

<__NSGlobalBlock__: 0x105a730d0>
<__NSMallocBlock__: 0x600000052c00>
<__NSStackBlock__: 0x7fff5a18b7e0>

注意看它们的地址,NSGlobalBlock的地址明显要短,因为它是在进程数据段上的。
blockC则是强行用__weak声明让其分配在栈上,这里会看到一个黄色的警告,大意就是指分配后就会被释放。就是说viewDidLoad这个方法return后这个block就会被释放。

动态分配和静态分配的区分是在哪里?观察一下就发现NSGlobalBlock类型是没有捕获局部变量的,它只是打印一一个字符串。通过NSString literal创建的字符串是放在常量区的,也就是数据段上。全局的block里没有引用任何堆或栈上的数据。另外如果将上面的例子中的int value = 10;改为const int value = 10;那么blockB将变成NSGlobalBlock,这是因为const修饰下value里的值会存储在常量区即数据段上,也就是不违反原则,只要block literal里没有引用栈或堆上的数据,那么这个block会自动变为NSGlobalBlock类型,这是编译器的优化。

在属性声明上,我们一般会用copy修饰一个Block属性。原因是什么?
在MRR或MRC(两个词都是指同一个玩意)中,block默认是在栈上创建的。如果我们将它赋值给一个成员变量,如果成员变量没有被copy修饰或在赋值的时候没有进行copy,那么在使用这个block成员变量的时候就会崩溃。

思考一下下面的代码。

@property(nonatomic, weak) void(^block)();

- (void)viewDidLoad {
[superviewDidLoad];

int value = 10;
void(^blockC)() = ^{
NSLog(@"just a block === %d", value);
     };

NSLog(@"%@", blockC);
     _block = blockC;

}

- (IBAction)action:(id)sender {
NSLog(@"%@", _block);
}

这代码在MRC下是会崩溃的。但ARC下就不会了,因为block默认就创建在堆上了。但是不是意味着ARC不用写copy来修饰block属性呢?当然不是了,上面已经说了,我们是可以强行在ARC上将一个block创建在栈上的。

相关文章

  • iOS block 为什么官方文档建议用 copy 修饰

    一、block 的三种类型block 三种类型:全局 block,堆 block、栈 block。全局 block...

  • iOS 常见面试题 -- block

    一、block的本质 二、block的类型 block 有三种类型分别如下: 如何区分block的类型 三、blo...

  • Block原理分析

    block类型 我们都知道block有三种类型:NSGlobalBlock、NSStackBlock、NSMall...

  • iOS Block

    Block的分类 Block有三种类型:全局Block,堆区Block,栈区Block 全局Block 当Bloc...

  • OC 基础-Block类型

    OC基础-Block(3)Block的类型Block有三种类型,可以通过调用class方法或者isa指针查看具体类...

  • iOS Block

    Block block 类型 block主要有三种类型 NSGlobalBlock:全局block,存储在全局区 ...

  • ios中block的三种形式

    Block有三种类型: __NSGlobalBlock __NSStackBlock __NSMallocBloc...

  • Block实现原理

    主要介绍block的类型和底层分析 block类型 block主要由三种类型 NSGlobalBlock:全局bl...

  • OC底层-block底层原理探究

    一、block的常见三种类型 1.1 NSGlobalBlock NSGlobalBlock 全局类型block,...

  • ios中block的深入理解

    block有三种类型:NSGlobalBlock,NSStackBlock,NSMallocBlock。 1. ...

网友评论

      本文标题:Block 有三种类型

      本文链接:https://www.haomeiwen.com/subject/jclqbftx.html