设为首页 加入收藏

TOP

block本质探寻三之block类型(一)
2019-08-26 07:06:40 】 浏览:54
Tags:block 本质 探寻 类型

一、oc代码

提示:看本文章之前,最好按顺序来看;

//代码

void test1()
{
    int age = 10;
    
    void(^block1)(void) = ^{
        NSLog(@"block1----");
    };
    
    void(^block2)(void) = ^{
        NSLog(@"block2----%d", age);
    };
    
    NSLog(@"block1-----\n%@ %@ %@ %@", [block1 class], [[block1 class] superclass], [[[block1 class] superclass] superclass], [[[[block1 class] superclass] superclass] superclass]);
    
    NSLog(@"block2-----\n%@ %@ %@ %@", [block2 class], [[block2 class] superclass], [[[block2 class] superclass] superclass], [[[[block2 class] superclass] superclass] superclass]);
    
    NSLog(@"block-----\n%@ %@ %@ %@", [^{
        NSLog(@"block----%d", age);
    } class], [[^{
        NSLog(@"block----%d", age);
    } class] superclass], [[[^{
        NSLog(@"block----%d", age);
    } class] superclass] superclass], [[[[^{
        NSLog(@"block----%d", age);
    } class] superclass] superclass] superclass]);
}

//打印

2019-01-10 14:36:04.290317+0800 MJ_TEST[3446:174827] block1-----
__NSGlobalBlock__ __NSGlobalBlock NSBlock NSObject
2019-01-10 14:36:04.290608+0800 MJ_TEST[3446:174827] block2-----
__NSMallocBlock__ __NSMallocBlock NSBlock NSObject
2019-01-10 14:36:04.290652+0800 MJ_TEST[3446:174827] block-----
__NSStackBlock__ __NSStackBlock NSBlock NSObject
Program ended with exit code: 0

分析:

1)三个block的类型分别为:__NSGlobalBlock__、__NSMallocBlock__、__NSStackBlock__,什么原因,往下看;

2)上述三种类型最终都是继承自NSBlock,而NSBlock又是继承自NSObject:此处又进一步说明block其实就是一个OC对象(前面的文章已经证明过);

说明:上述结果是在ARC模式下打印的结果,现在我们看看MRC的打印情况

//设置

//打印

2019-01-10 15:05:50.667948+0800 MJ_TEST[3576:189745] block1-----
__NSGlobalBlock__ __NSGlobalBlock NSBlock NSObject
2019-01-10 15:05:50.668257+0800 MJ_TEST[3576:189745] block2-----
__NSStackBlock__ __NSStackBlock NSBlock NSObject
2019-01-10 15:05:50.668279+0800 MJ_TEST[3576:189745] block-----
__NSStackBlock__ __NSStackBlock NSBlock NSObject
Program ended with exit code: 0

分析:发现MRC模式下,三种block类型:__NSGlobalBlock__、__NSStackBlock__、__NSStackBlock__,为什么中间的类型由malloc变成了stack?这是因为ARC系统自动帮助我们对block进行了copy操作;

补充一下:clang成C++代码,我们看下

struct __test1_block_impl_0 {
  struct __block_impl impl;
  struct __test1_block_desc_0* Desc;
  __test1_block_impl_0(void *fp, struct __test1_block_desc_0 *desc, int flags=0) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};


struct __test1_block_impl_1 {
  struct __block_impl impl;
  struct __test1_block_desc_1* Desc;
  int age;
  __test1_block_impl_1(void *fp, struct __test1_block_desc_1 *desc, int _age, int flags=0) : age(_age) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};


struct __test1_block_impl_2 {
  struct __block_impl impl;
  struct __test1_block_desc_2* Desc;
  int age;
  __test1_block_impl_2(void *fp, struct __test1_block_desc_2 *desc, int _age, int flags=0) : age(_age) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};

分析:发现都是_NSConcreteStackBlock类型,不能正确反应block的实质类型(据说是LLVM编译器版本的问题,而clang又是LLVM的一部分);

 

二、原因分析

1)程序内存结构

<1>首先,程序的内存结构分为:程序区(代码区)、数据区(全局区)、堆区、栈区;

<2>全局变量、static类型的局部变量存放在数据区,内存直到程序结束才自动释放;auto类型的局部

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇谈谈iOS获取调用链 下一篇关于NSStringFromClass的一点见解

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目